From 954a1eb75f2abc81da1e09701d700674f0baddfb Mon Sep 17 00:00:00 2001 From: Stefan Radomski Date: Tue, 25 Oct 2016 13:59:18 +0200 Subject: Worked on PROMELA transformation --- CMakeLists.txt | 2 + apps/uscxml-transform.cpp | 27 +- config.h.in | 2 + contrib/cmake/BuildLibEvent.cmake | 2 + contrib/patches/libevent/sierra.kqueue.c | 475 ++++ src/bindings/swig/uscxml_beautify.i | 4 +- src/bindings/swig/wrapped/WrappedActionLanguage.h | 8 +- src/bindings/swig/wrapped/WrappedDataModel.h | 111 +- .../swig/wrapped/WrappedExecutableContent.cpp | 14 +- .../swig/wrapped/WrappedExecutableContent.h | 24 +- src/bindings/swig/wrapped/WrappedIOProcessor.cpp | 2 +- src/bindings/swig/wrapped/WrappedIOProcessor.h | 30 +- .../swig/wrapped/WrappedInterpreterMonitor.cpp | 158 +- .../swig/wrapped/WrappedInterpreterMonitor.h | 84 +- src/bindings/swig/wrapped/WrappedInvoker.cpp | 2 +- src/bindings/swig/wrapped/WrappedInvoker.h | 64 +- src/uscxml/Interpreter.cpp | 4 +- src/uscxml/Interpreter.h | 24 +- src/uscxml/debug/Breakpoint.cpp | 4 +- src/uscxml/debug/Breakpoint.h | 4 +- src/uscxml/debug/DebugSession.cpp | 142 +- src/uscxml/debug/DebugSession.h | 12 +- src/uscxml/debug/Debugger.cpp | 84 +- src/uscxml/debug/Debugger.h | 58 +- src/uscxml/debug/DebuggerServlet.cpp | 6 +- src/uscxml/debug/DebuggerServlet.h | 8 +- src/uscxml/debug/InterpreterIssue.cpp | 4 +- src/uscxml/interpreter/BasicContentExecutor.cpp | 20 +- src/uscxml/interpreter/BasicEventQueue.cpp | 20 +- src/uscxml/interpreter/BasicEventQueue.h | 6 +- src/uscxml/interpreter/ContentExecutorImpl.h | 2 +- src/uscxml/interpreter/EventQueue.cpp | 2 +- src/uscxml/interpreter/EventQueue.h | 2 +- src/uscxml/interpreter/EventQueueImpl.h | 2 +- src/uscxml/interpreter/FastMicroStep.cpp | 96 +- src/uscxml/interpreter/FastMicroStep.h | 16 +- src/uscxml/interpreter/InterpreterImpl.cpp | 44 +- src/uscxml/interpreter/InterpreterImpl.h | 47 +- src/uscxml/interpreter/InterpreterMonitor.h | 4 +- src/uscxml/interpreter/MicroStepImpl.h | 4 +- src/uscxml/plugins/DataModelImpl.h | 5 +- src/uscxml/plugins/Factory.cpp | 91 +- src/uscxml/plugins/datamodel/CMakeLists.txt | 11 + src/uscxml/plugins/datamodel/c89/C89DataModel.cpp | 10 +- src/uscxml/plugins/datamodel/c89/C89DataModel.h | 4 +- .../ecmascript/JavaScriptCore/JSCDataModel.cpp | 34 +- .../datamodel/ecmascript/v8/V8DataModel.cpp | 34 +- src/uscxml/plugins/datamodel/lua/LuaDataModel.cpp | 136 +- .../plugins/datamodel/promela/PromelaDataModel.cpp | 728 ++++++ .../plugins/datamodel/promela/PromelaDataModel.h | 102 + .../plugins/datamodel/promela/PromelaParser.cpp | 298 +++ .../plugins/datamodel/promela/PromelaParser.h | 106 + .../plugins/datamodel/promela/parser/promela.l | 117 + .../datamodel/promela/parser/promela.lex.yy.cpp | 2598 +++++++++++++++++++ .../datamodel/promela/parser/promela.tab.cpp | 2634 ++++++++++++++++++++ .../datamodel/promela/parser/promela.tab.hpp | 180 ++ .../plugins/datamodel/promela/parser/promela.ypp | 254 ++ .../plugins/invoker/dirmon/DirMonInvoker.cpp | 16 +- src/uscxml/plugins/invoker/dirmon/DirMonInvoker.h | 6 +- .../ioprocessor/basichttp/BasicHTTPIOProcessor.cpp | 4 +- src/uscxml/server/HTTPServer.cpp | 22 +- src/uscxml/transform/ChartToC.cpp | 6 +- src/uscxml/transform/ChartToC.h | 2 +- src/uscxml/transform/ChartToPromela.cpp | 2625 +++++++++++++++++++ src/uscxml/transform/ChartToPromela.h | 130 + src/uscxml/transform/ChartToVHDL.cpp | 2558 +++++++++---------- src/uscxml/transform/ChartToVHDL.h | 26 +- .../transform/promela/PromelaCodeAnalyzer.cpp | 596 +++++ src/uscxml/transform/promela/PromelaCodeAnalyzer.h | 150 ++ src/uscxml/transform/promela/PromelaInlines.cpp | 165 ++ src/uscxml/transform/promela/PromelaInlines.h | 113 + src/uscxml/util/DOM.cpp | 22 +- src/uscxml/util/DOM.h | 140 +- src/uscxml/util/Predicates.cpp | 52 +- src/uscxml/util/URL.cpp | 28 +- src/uscxml/util/URL.h | 2 +- test/CMakeLists.txt | 11 +- .../apache/commons/scxml2/JexlEvaluator.java | 4 +- .../java/org/uscxml/dm/jexl/JEXLDataModel.java | 25 +- .../java/org/uscxml/examples/DataModelExample.java | 4 +- .../bindings/java/org/uscxml/helper/StopWatch.java | 22 + .../java/org/uscxml/tests/JexlDataModelTest.java | 35 +- test/ctest/scripts/run_promela_test.cmake | 6 +- test/src/test-bindings.cpp | 2 +- test/src/test-c89-parser.cpp | 182 +- test/src/test-promela-parser.cpp | 323 +++ test/src/test-stress.cpp | 44 +- test/uscxml/promela/test-complete.scxml | 154 ++ test/uscxml/promela/test-event-source-auto.scxml | 45 + test/uscxml/promela/test-event-source.scxml | 39 + test/uscxml/promela/test-history.scxml | 16 + test/uscxml/promela/test-ltl.scxml | 16 + test/uscxml/promela/test-non-progress.scxml | 17 + test/uscxml/promela/test-progress-label.scxml | 20 + test/uscxml/promela/test-simple.scxml | 15 + test/uscxml/promela/test-syntax.scxml | 132 + test/w3c/confPromela.xsl | 2 +- test/w3c/promela/robots.txt | 103 + 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 | 45 + test/w3c/promela/test151.scxml | 45 + test/w3c/promela/test152.scxml | 51 + test/w3c/promela/test153.scxml | 42 + test/w3c/promela/test155.scxml | 31 + test/w3c/promela/test156.scxml | 33 + 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 | 47 + test/w3c/promela/test352.scxml | 32 + 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/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 | 32 + 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 | 25 + 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 + 292 files changed, 21104 insertions(+), 2314 deletions(-) create mode 100644 contrib/patches/libevent/sierra.kqueue.c create mode 100644 src/uscxml/plugins/datamodel/promela/PromelaDataModel.cpp create mode 100644 src/uscxml/plugins/datamodel/promela/PromelaDataModel.h create mode 100644 src/uscxml/plugins/datamodel/promela/PromelaParser.cpp create mode 100644 src/uscxml/plugins/datamodel/promela/PromelaParser.h create mode 100644 src/uscxml/plugins/datamodel/promela/parser/promela.l create mode 100644 src/uscxml/plugins/datamodel/promela/parser/promela.lex.yy.cpp create mode 100644 src/uscxml/plugins/datamodel/promela/parser/promela.tab.cpp create mode 100644 src/uscxml/plugins/datamodel/promela/parser/promela.tab.hpp create mode 100644 src/uscxml/plugins/datamodel/promela/parser/promela.ypp create mode 100644 src/uscxml/transform/ChartToPromela.cpp create mode 100644 src/uscxml/transform/ChartToPromela.h create mode 100644 src/uscxml/transform/promela/PromelaCodeAnalyzer.cpp create mode 100644 src/uscxml/transform/promela/PromelaCodeAnalyzer.h create mode 100644 src/uscxml/transform/promela/PromelaInlines.cpp create mode 100644 src/uscxml/transform/promela/PromelaInlines.h create mode 100644 test/bindings/java/org/uscxml/helper/StopWatch.java create mode 100644 test/src/test-promela-parser.cpp create mode 100644 test/uscxml/promela/test-complete.scxml create mode 100644 test/uscxml/promela/test-event-source-auto.scxml create mode 100644 test/uscxml/promela/test-event-source.scxml create mode 100644 test/uscxml/promela/test-history.scxml create mode 100644 test/uscxml/promela/test-ltl.scxml create mode 100644 test/uscxml/promela/test-non-progress.scxml create mode 100644 test/uscxml/promela/test-progress-label.scxml create mode 100644 test/uscxml/promela/test-simple.scxml create mode 100644 test/uscxml/promela/test-syntax.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/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 diff --git a/CMakeLists.txt b/CMakeLists.txt index 1466df7..87fc2e5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -385,6 +385,8 @@ if (WITH_DM_C89) endif() endif() +OPTION(WITH_DM_PROMELA "Do build with promela datamodel support" ON) + add_subdirectory(src/uscxml) add_subdirectory(src/bindings) diff --git a/apps/uscxml-transform.cpp b/apps/uscxml-transform.cpp index de0c594..649b61b 100644 --- a/apps/uscxml-transform.cpp +++ b/apps/uscxml-transform.cpp @@ -3,6 +3,7 @@ #include "uscxml/util/String.h" #include "uscxml/transform/ChartToC.h" #include "uscxml/transform/ChartToVHDL.h" +#include "uscxml/transform/ChartToPROMELA.h" #include @@ -29,7 +30,7 @@ void printUsageAndExit(const char* progName) { 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()); - printf(" [-t c|pml|flat|min|tex] [-a {OPTIONS}] [-v] [-lN]"); + printf(" [-t c|pml|flat|min] [-a {OPTIONS}] [-v] [-lN]"); #ifdef BUILD_AS_PLUGINS printf(" [-p pluginPath]"); #endif @@ -41,7 +42,6 @@ void printUsageAndExit(const char* progName) { printf("\t-t vhdl : convert to VHDL hardware description\n"); printf("\t-t flat : flatten to SCXML state-machine\n"); printf("\t-t min : minimize SCXML state-chart\n"); - printf("\t-t tex : write global state transition table as tex file\n"); printf("\t-a {OPTIONS} : annotate SCXML elements with comma seperated options\n"); printf("\t priority - transitions with their priority for transition selection\n"); printf("\t exitset - annotate all transitions with their exit sets\n"); @@ -201,7 +201,6 @@ int main(int argc, char** argv) { outType != "c" && outType != "vhdl" && outType != "min" && - outType != "tex" && std::find(options.begin(), options.end(), "priority") == options.end() && std::find(options.begin(), options.end(), "domain") == options.end() && std::find(options.begin(), options.end(), "conflicts") == options.end() && @@ -303,17 +302,17 @@ int main(int argc, char** argv) { exit(EXIT_SUCCESS); } -// if (outType == "pml") { -// if (outputFile.size() == 0 || outputFile == "-") { -// ChartToPromela::transform(interpreter).writeTo(std::cout); -// } else { -// std::ofstream outStream; -// outStream.open(outputFile.c_str()); -// ChartToPromela::transform(interpreter).writeTo(outStream); -// outStream.close(); -// } -// exit(EXIT_SUCCESS); -// } + if (outType == "pml") { + if (outputFile.size() == 0 || outputFile == "-") { + ChartToPromela::transform(interpreter).writeTo(std::cout); + } else { + std::ofstream outStream; + outStream.open(outputFile.c_str()); + ChartToPromela::transform(interpreter).writeTo(outStream); + outStream.close(); + } + exit(EXIT_SUCCESS); + } // if (outType == "tex") { // if (outputFile.size() == 0 || outputFile == "-") { diff --git a/config.h.in b/config.h.in index 074b072..e8b69c1 100644 --- a/config.h.in +++ b/config.h.in @@ -69,6 +69,8 @@ #cmakedefine WITH_DM_ECMA_JSC #cmakedefine WITH_DM_LUA #cmakedefine WITH_DM_C89 +#cmakedefine WITH_DM_PROMELA + /** Optional libraries we found */ #cmakedefine UMUNDO_FOUND diff --git a/contrib/cmake/BuildLibEvent.cmake b/contrib/cmake/BuildLibEvent.cmake index 79fed51..4e4e7af 100644 --- a/contrib/cmake/BuildLibEvent.cmake +++ b/contrib/cmake/BuildLibEvent.cmake @@ -29,6 +29,8 @@ else () URL_MD5 c4c56f986aa985677ca1db89630a2e11 BUILD_IN_SOURCE 0 PREFIX ${CMAKE_BINARY_DIR}/deps/libevent + PATCH_COMMAND + ${CMAKE_COMMAND} -E copy "${PROJECT_SOURCE_DIR}/contrib/patches/libevent/sierra.kqueue.c" /kqueue.c CONFIGURE_COMMAND ${FORCE_FPIC} /configure --enable-static --enable-shared --disable-openssl --prefix= ) diff --git a/contrib/patches/libevent/sierra.kqueue.c b/contrib/patches/libevent/sierra.kqueue.c new file mode 100644 index 0000000..f74dfe1 --- /dev/null +++ b/contrib/patches/libevent/sierra.kqueue.c @@ -0,0 +1,475 @@ +/* $OpenBSD: kqueue.c,v 1.5 2002/07/10 14:41:31 art Exp $ */ + +/* + * Copyright 2000-2007 Niels Provos + * Copyright 2007-2012 Niels Provos and Nick Mathewson + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "event2/event-config.h" + +#define _GNU_SOURCE + +#include +#ifdef _EVENT_HAVE_SYS_TIME_H +#include +#endif +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef _EVENT_HAVE_INTTYPES_H +#include +#endif + +/* Some platforms apparently define the udata field of struct kevent as + * intptr_t, whereas others define it as void*. There doesn't seem to be an + * easy way to tell them apart via autoconf, so we need to use OS macros. */ +#if defined(_EVENT_HAVE_INTTYPES_H) && !defined(__OpenBSD__) && !defined(__FreeBSD__) && !defined(__darwin__) && !defined(__APPLE__) +#define PTR_TO_UDATA(x) ((intptr_t)(x)) +#define INT_TO_UDATA(x) ((intptr_t)(x)) +#else +#define PTR_TO_UDATA(x) (x) +#define INT_TO_UDATA(x) ((void*)(x)) +#endif + +#include "event-internal.h" +#include "log-internal.h" +#include "evmap-internal.h" +#include "event2/thread.h" +#include "evthread-internal.h" +#include "changelist-internal.h" + +#define NEVENT 64 + +struct kqop { + struct kevent *changes; + int changes_size; + + struct kevent *events; + int events_size; + int kq; + pid_t pid; +}; + +static void kqop_free(struct kqop *kqop); + +static void *kq_init(struct event_base *); +static int kq_sig_add(struct event_base *, int, short, short, void *); +static int kq_sig_del(struct event_base *, int, short, short, void *); +static int kq_dispatch(struct event_base *, struct timeval *); +static void kq_dealloc(struct event_base *); + +const struct eventop kqops = { + "kqueue", + kq_init, + event_changelist_add, + event_changelist_del, + kq_dispatch, + kq_dealloc, + 1 /* need reinit */, + EV_FEATURE_ET|EV_FEATURE_O1|EV_FEATURE_FDS, + EVENT_CHANGELIST_FDINFO_SIZE +}; + +static const struct eventop kqsigops = { + "kqueue_signal", + NULL, + kq_sig_add, + kq_sig_del, + NULL, + NULL, + 1 /* need reinit */, + 0, + 0 +}; + +static void * +kq_init(struct event_base *base) +{ + int kq = -1; + struct kqop *kqueueop = NULL; + + if (!(kqueueop = mm_calloc(1, sizeof(struct kqop)))) + return (NULL); + +/* Initialize the kernel queue */ + + if ((kq = kqueue()) == -1) { + event_warn("kqueue"); + goto err; + } + + kqueueop->kq = kq; + + kqueueop->pid = getpid(); + + /* Initialize fields */ + kqueueop->changes = mm_calloc(NEVENT, sizeof(struct kevent)); + if (kqueueop->changes == NULL) + goto err; + kqueueop->events = mm_calloc(NEVENT, sizeof(struct kevent)); + if (kqueueop->events == NULL) + goto err; + kqueueop->events_size = kqueueop->changes_size = NEVENT; + + /* Check for Mac OS X kqueue bug. */ + memset(&kqueueop->changes[0], 0, sizeof kqueueop->changes[0]); + kqueueop->changes[0].ident = -1; + kqueueop->changes[0].filter = EVFILT_READ; + kqueueop->changes[0].flags = EV_ADD; + /* + * If kqueue works, then kevent will succeed, and it will + * stick an error in events[0]. If kqueue is broken, then + * kevent will fail. + */ + if (kevent(kq, + kqueueop->changes, 1, kqueueop->events, NEVENT, NULL) != 1 || + (int)kqueueop->events[0].ident != -1 || + !(kqueueop->events[0].flags & EV_ERROR)) { + event_warn("%s: detected broken kqueue; not using.", __func__); + goto err; + } + + base->evsigsel = &kqsigops; + + return (kqueueop); +err: + if (kqueueop) + kqop_free(kqueueop); + + return (NULL); +} + +static void +kq_sighandler(int sig) +{ + /* Do nothing here */ +} + +#define ADD_UDATA 0x30303 + +static void +kq_setup_kevent(struct kevent *out, evutil_socket_t fd, int filter, short change) +{ + memset(out, 0, sizeof(struct kevent)); + out->ident = fd; + out->filter = filter; + + if (change & EV_CHANGE_ADD) { + out->flags = EV_ADD; + /* We set a magic number here so that we can tell 'add' + * errors from 'del' errors. */ + out->udata = INT_TO_UDATA(ADD_UDATA); + if (change & EV_ET) + out->flags |= EV_CLEAR; +#ifdef NOTE_EOF + /* Make it behave like select() and poll() */ + if (filter == EVFILT_READ) + out->fflags = NOTE_EOF; +#endif + } else { + EVUTIL_ASSERT(change & EV_CHANGE_DEL); + out->flags = EV_DELETE; + } +} + +static int +kq_build_changes_list(const struct event_changelist *changelist, + struct kqop *kqop) +{ + int i; + int n_changes = 0; + + for (i = 0; i < changelist->n_changes; ++i) { + struct event_change *in_ch = &changelist->changes[i]; + struct kevent *out_ch; + if (n_changes >= kqop->changes_size - 1) { + int newsize = kqop->changes_size * 2; + struct kevent *newchanges; + + newchanges = mm_realloc(kqop->changes, + newsize * sizeof(struct kevent)); + if (newchanges == NULL) { + event_warn("%s: realloc", __func__); + return (-1); + } + kqop->changes = newchanges; + kqop->changes_size = newsize; + } + if (in_ch->read_change) { + out_ch = &kqop->changes[n_changes++]; + kq_setup_kevent(out_ch, in_ch->fd, EVFILT_READ, + in_ch->read_change); + } + if (in_ch->write_change) { + out_ch = &kqop->changes[n_changes++]; + kq_setup_kevent(out_ch, in_ch->fd, EVFILT_WRITE, + in_ch->write_change); + } + } + return n_changes; +} + +static int +kq_grow_events(struct kqop *kqop, size_t new_size) +{ + struct kevent *newresult; + + newresult = mm_realloc(kqop->events, + new_size * sizeof(struct kevent)); + + if (newresult) { + kqop->events = newresult; + kqop->events_size = new_size; + return 0; + } else { + return -1; + } +} + +static int +kq_dispatch(struct event_base *base, struct timeval *tv) +{ + struct kqop *kqop = base->evbase; + struct kevent *events = kqop->events; + struct kevent *changes; + struct timespec ts, *ts_p = NULL; + int i, n_changes, res; + + if (tv != NULL) { + TIMEVAL_TO_TIMESPEC(tv, &ts); + ts_p = &ts; + } + + /* Build "changes" from "base->changes" */ + EVUTIL_ASSERT(kqop->changes); + n_changes = kq_build_changes_list(&base->changelist, kqop); + if (n_changes < 0) + return -1; + + event_changelist_remove_all(&base->changelist, base); + + /* steal the changes array in case some broken code tries to call + * dispatch twice at once. */ + changes = kqop->changes; + kqop->changes = NULL; + + /* Make sure that 'events' is at least as long as the list of changes: + * otherwise errors in the changes can get reported as a -1 return + * value from kevent() rather than as EV_ERROR events in the events + * array. + * + * (We could instead handle -1 return values from kevent() by + * retrying with a smaller changes array or a larger events array, + * but this approach seems less risky for now.) + */ + if (kqop->events_size < n_changes) { + int new_size = kqop->events_size; + do { + new_size *= 2; + } while (new_size < n_changes); + + kq_grow_events(kqop, new_size); + events = kqop->events; + } + + EVBASE_RELEASE_LOCK(base, th_base_lock); + + res = kevent(kqop->kq, changes, n_changes, + events, kqop->events_size, ts_p); + + EVBASE_ACQUIRE_LOCK(base, th_base_lock); + + EVUTIL_ASSERT(kqop->changes == NULL); + kqop->changes = changes; + + if (res == -1) { + if (errno != EINTR) { + event_warn("kevent"); + return (-1); + } + + return (0); + } + + event_debug(("%s: kevent reports %d", __func__, res)); + + for (i = 0; i < res; i++) { + int which = 0; + + if (events[i].flags & EV_ERROR) { + switch (events[i].data) { + + /* Can occur on delete if we are not currently + * watching any events on this fd. That can + * happen when the fd was closed and another + * file was opened with that fd. */ + case ENOENT: + /* Can occur for reasons not fully understood + * on FreeBSD. */ + case EINVAL: + continue; + + /* Can occur on a delete if the fd is closed. */ + case EBADF: + /* XXXX On NetBSD, we can also get EBADF if we + * try to add the write side of a pipe, but + * the read side has already been closed. + * Other BSDs call this situation 'EPIPE'. It + * would be good if we had a way to report + * this situation. */ + continue; + /* These two can occur on an add if the fd was one side + * of a pipe, and the other side was closed. */ + case EPERM: + case EPIPE: + /* Report read events, if we're listening for + * them, so that the user can learn about any + * add errors. (If the operation was a + * delete, then udata should be cleared.) */ + if (events[i].udata) { + /* The operation was an add: + * report the error as a read. */ + which |= EV_READ; + break; + } else { + /* The operation was a del: + * report nothing. */ + continue; + } + + /* Other errors shouldn't occur. */ + default: + errno = events[i].data; + return (-1); + } + } else if (events[i].filter == EVFILT_READ) { + which |= EV_READ; + } else if (events[i].filter == EVFILT_WRITE) { + which |= EV_WRITE; + } else if (events[i].filter == EVFILT_SIGNAL) { + which |= EV_SIGNAL; + } + + if (!which) + continue; + + if (events[i].filter == EVFILT_SIGNAL) { + evmap_signal_active(base, events[i].ident, 1); + } else { + evmap_io_active(base, events[i].ident, which | EV_ET); + } + } + + if (res == kqop->events_size) { + /* We used all the events space that we have. Maybe we should + make it bigger. */ + kq_grow_events(kqop, kqop->events_size * 2); + } + + return (0); +} + +static void +kqop_free(struct kqop *kqop) +{ + if (kqop->changes) + mm_free(kqop->changes); + if (kqop->events) + mm_free(kqop->events); + if (kqop->kq >= 0 && kqop->pid == getpid()) + close(kqop->kq); + memset(kqop, 0, sizeof(struct kqop)); + mm_free(kqop); +} + +static void +kq_dealloc(struct event_base *base) +{ + struct kqop *kqop = base->evbase; + evsig_dealloc(base); + kqop_free(kqop); +} + +/* signal handling */ +static int +kq_sig_add(struct event_base *base, int nsignal, short old, short events, void *p) +{ + struct kqop *kqop = base->evbase; + struct kevent kev; + struct timespec timeout = { 0, 0 }; + (void)p; + + EVUTIL_ASSERT(nsignal >= 0 && nsignal < NSIG); + + memset(&kev, 0, sizeof(kev)); + kev.ident = nsignal; + kev.filter = EVFILT_SIGNAL; + kev.flags = EV_ADD; + + /* Be ready for the signal if it is sent any + * time between now and the next call to + * kq_dispatch. */ + if (kevent(kqop->kq, &kev, 1, NULL, 0, &timeout) == -1) + return (-1); + + /* XXXX The manpage suggest we could use SIG_IGN instead of a + * do-nothing handler */ + if (_evsig_set_handler(base, nsignal, kq_sighandler) == -1) + return (-1); + + return (0); +} + +static int +kq_sig_del(struct event_base *base, int nsignal, short old, short events, void *p) +{ + struct kqop *kqop = base->evbase; + struct kevent kev; + + struct timespec timeout = { 0, 0 }; + (void)p; + + EVUTIL_ASSERT(nsignal >= 0 && nsignal < NSIG); + + memset(&kev, 0, sizeof(kev)); + kev.ident = nsignal; + kev.filter = EVFILT_SIGNAL; + kev.flags = EV_DELETE; + + /* Because we insert signal events + * immediately, we need to delete them + * immediately, too */ + if (kevent(kqop->kq, &kev, 1, NULL, 0, &timeout) == -1) + return (-1); + + if (_evsig_restore_handler(base, nsignal) == -1) + return (-1); + + return (0); +} diff --git a/src/bindings/swig/uscxml_beautify.i b/src/bindings/swig/uscxml_beautify.i index 0c17e2a..159bcaa 100644 --- a/src/bindings/swig/uscxml_beautify.i +++ b/src/bindings/swig/uscxml_beautify.i @@ -2,8 +2,8 @@ %rename(ActionLanguage) WrappedActionLanguage; %rename(NativeDataModel) DataModel; %rename(DataModel) WrappedDataModel; -%rename(NativeDataModelExtension) DataModelExtension; -%rename(DataModelExtension) WrappedDataModelExtension; +//%rename(NativeDataModelExtension) DataModelExtension; +//%rename(DataModelExtension) WrappedDataModelExtension; %rename(NativeExecutableContent) ExecutableContent; %rename(ExecutableContent) WrappedExecutableContent; %rename(NativeInvoker) Invoker; diff --git a/src/bindings/swig/wrapped/WrappedActionLanguage.h b/src/bindings/swig/wrapped/WrappedActionLanguage.h index f26329e..55e009c 100644 --- a/src/bindings/swig/wrapped/WrappedActionLanguage.h +++ b/src/bindings/swig/wrapped/WrappedActionLanguage.h @@ -19,7 +19,7 @@ #ifndef WRAPPEDACTIONLANGUAGE_H_020AFC96 #define WRAPPEDACTIONLANGUAGE_H_020AFC96 - + #include #include #include @@ -37,10 +37,10 @@ class DataModelImpl; class WrappedActionLanguage : public ActionLanguage { public: - WrappedActionLanguage(); - virtual ~WrappedActionLanguage(); + WrappedActionLanguage(); + virtual ~WrappedActionLanguage(); - void setDataModel(DataModelImpl* dm); + void setDataModel(DataModelImpl* dm); }; } diff --git a/src/bindings/swig/wrapped/WrappedDataModel.h b/src/bindings/swig/wrapped/WrappedDataModel.h index 49a3482..1fefcbe 100644 --- a/src/bindings/swig/wrapped/WrappedDataModel.h +++ b/src/bindings/swig/wrapped/WrappedDataModel.h @@ -35,62 +35,65 @@ namespace uscxml { class WrappedDataModel : public DataModelImpl { public: - WrappedDataModel(); - virtual ~WrappedDataModel(); - - virtual std::shared_ptr create(DataModelCallbacks* callbacks) { - std::shared_ptr dm(create()); - dm->callbacks = callbacks; - return dm; - } - - virtual std::list getNames() { - return std::list(); - } - - virtual WrappedDataModel* create() { - return new WrappedDataModel(); - } - - virtual bool isValidSyntax(const std::string& expr) { - return true; - } - - virtual void setEvent(const Event& event) {} - - // foreach - virtual uint32_t getLength(const std::string& expr) { - return 0; - } - - virtual void setForeach(const std::string& item, - const std::string& array, - const std::string& index, - uint32_t iteration) {} - - virtual Data getAsData(const std::string& content) { - return Data(); - } - virtual Data evalAsData(const std::string& expr) { - return Data(); - } - virtual bool evalAsBool(const std::string& expr) { - return true; - } - - virtual bool isDeclared(const std::string& expr) { - return true; - } - - virtual void assign(const std::string& location, const Data& data) {} - virtual void init(const std::string& location, const Data& data) {} - - virtual std::string andExpressions(std::list) { - return ""; - } + WrappedDataModel(); + virtual ~WrappedDataModel(); + + virtual std::shared_ptr create(DataModelCallbacks* callbacks) { + std::shared_ptr dm(create()); + dm->callbacks = callbacks; + return dm; + } + + virtual std::list getNames() { + return std::list(); + } + + virtual WrappedDataModel* create() { + return new WrappedDataModel(); + } + + virtual bool isValidSyntax(const std::string& expr) { + return true; + } + + virtual void setEvent(const Event& event) {} + + // foreach + virtual uint32_t getLength(const std::string& expr) { + return 0; + } + + virtual void setForeach(const std::string& item, + const std::string& array, + const std::string& index, + uint32_t iteration) {} + + virtual Data getAsData(const std::string& content) { + return Data(); + } + virtual Data evalAsData(const std::string& expr) { + return Data(); + } + virtual bool evalAsBool(const std::string& expr) { + return true; + } + + virtual bool isDeclared(const std::string& expr) { + return true; + } + + virtual void assign(const std::string& location, const Data& data) {} + virtual void init(const std::string& location, const Data& data) {} + + virtual void addExtension(DataModelExtension* ext) { + } + + virtual std::string andExpressions(std::list) { + return ""; + } protected: - DataModelCallbacks* callbacks; + DataModelCallbacks* callbacks; }; } diff --git a/src/bindings/swig/wrapped/WrappedExecutableContent.cpp b/src/bindings/swig/wrapped/WrappedExecutableContent.cpp index 09aa6fd..3587cb5 100644 --- a/src/bindings/swig/wrapped/WrappedExecutableContent.cpp +++ b/src/bindings/swig/wrapped/WrappedExecutableContent.cpp @@ -28,16 +28,16 @@ WrappedExecutableContent::WrappedExecutableContent() {} WrappedExecutableContent::~WrappedExecutableContent() {} void WrappedExecutableContent::enterElement(XERCESC_NS::DOMElement* element) { - std::stringstream ss; - ss << *element; - enterElement(ss.str()); + std::stringstream ss; + ss << *element; + enterElement(ss.str()); } void WrappedExecutableContent::exitElement(XERCESC_NS::DOMElement* element) { - std::stringstream ss; - ss << *element; - exitElement(ss.str()); + std::stringstream ss; + ss << *element; + exitElement(ss.str()); } - + } \ No newline at end of file diff --git a/src/bindings/swig/wrapped/WrappedExecutableContent.h b/src/bindings/swig/wrapped/WrappedExecutableContent.h index 0ba8d3e..6786b0a 100644 --- a/src/bindings/swig/wrapped/WrappedExecutableContent.h +++ b/src/bindings/swig/wrapped/WrappedExecutableContent.h @@ -35,9 +35,9 @@ public: virtual ~WrappedExecutableContent(); virtual std::shared_ptr create(InterpreterImpl* interpreter) { - std::shared_ptr ec(new WrappedExecutableContent()); - return ec; - } + std::shared_ptr ec(new WrappedExecutableContent()); + return ec; + } virtual std::string getLocalName() { return ""; @@ -47,16 +47,16 @@ public: return "http://www.w3.org/2005/07/scxml"; } - - void enterElement(XERCESC_NS::DOMElement* element); - virtual void enterElement(const std::string& elementXML) {} - - void exitElement(XERCESC_NS::DOMElement* element); - virtual void exitElement(const std::string& elementXML) {} - virtual bool processChildren() { - return true; - } + void enterElement(XERCESC_NS::DOMElement* element); + virtual void enterElement(const std::string& elementXML) {} + + void exitElement(XERCESC_NS::DOMElement* element); + virtual void exitElement(const std::string& elementXML) {} + + virtual bool processChildren() { + return true; + } }; diff --git a/src/bindings/swig/wrapped/WrappedIOProcessor.cpp b/src/bindings/swig/wrapped/WrappedIOProcessor.cpp index d034bc3..6c96840 100644 --- a/src/bindings/swig/wrapped/WrappedIOProcessor.cpp +++ b/src/bindings/swig/wrapped/WrappedIOProcessor.cpp @@ -22,7 +22,7 @@ namespace uscxml { WrappedIOProcessor::WrappedIOProcessor(InterpreterImpl* interpreter) { - _interpreter = interpreter; + _interpreter = interpreter; } WrappedIOProcessor::~WrappedIOProcessor() {} diff --git a/src/bindings/swig/wrapped/WrappedIOProcessor.h b/src/bindings/swig/wrapped/WrappedIOProcessor.h index aa5f967..f1820a4 100644 --- a/src/bindings/swig/wrapped/WrappedIOProcessor.h +++ b/src/bindings/swig/wrapped/WrappedIOProcessor.h @@ -39,23 +39,23 @@ public: WrappedIOProcessor(InterpreterImpl* interpreter); virtual ~WrappedIOProcessor(); - virtual std::list getNames() { - return std::list(); - }; + virtual std::list getNames() { + return std::list(); + }; - virtual std::shared_ptr create(InterpreterImpl* interpreter) { - std::shared_ptr ioProc = std::shared_ptr(new WrappedIOProcessor(interpreter)); - return ioProc; - } - - virtual void eventFromSCXML(const std::string& target, const Event& event) {} - virtual bool isValidTarget(const std::string& target) { - return true; - } + virtual std::shared_ptr create(InterpreterImpl* interpreter) { + std::shared_ptr ioProc = std::shared_ptr(new WrappedIOProcessor(interpreter)); + return ioProc; + } - virtual Data getDataModelVariables() { - return Data(); - } + virtual void eventFromSCXML(const std::string& target, const Event& event) {} + virtual bool isValidTarget(const std::string& target) { + return true; + } + + virtual Data getDataModelVariables() { + return Data(); + } }; } diff --git a/src/bindings/swig/wrapped/WrappedInterpreterMonitor.cpp b/src/bindings/swig/wrapped/WrappedInterpreterMonitor.cpp index cdb46de..f563539 100644 --- a/src/bindings/swig/wrapped/WrappedInterpreterMonitor.cpp +++ b/src/bindings/swig/wrapped/WrappedInterpreterMonitor.cpp @@ -26,122 +26,122 @@ namespace uscxml { using namespace XERCESC_NS; - + WrappedInterpreterMonitor::WrappedInterpreterMonitor() {} WrappedInterpreterMonitor::~WrappedInterpreterMonitor() {} void WrappedInterpreterMonitor::beforeExitingState(Interpreter& interpreter, const XERCESC_NS::DOMElement* state) { - std::stringstream ss; - ss << *state; - beforeExitingState(ATTR(state, "id"), DOMUtils::xPathForNode(state), ss.str()); + std::stringstream ss; + ss << *state; + beforeExitingState(ATTR(state, "id"), DOMUtils::xPathForNode(state), ss.str()); } void WrappedInterpreterMonitor::afterExitingState(Interpreter& interpreter, const XERCESC_NS::DOMElement* state) { - std::stringstream ss; - ss << *state; - afterExitingState(ATTR(state, "id"), DOMUtils::xPathForNode(state), ss.str()); + std::stringstream ss; + ss << *state; + afterExitingState(ATTR(state, "id"), DOMUtils::xPathForNode(state), ss.str()); } void WrappedInterpreterMonitor::beforeExecutingContent(Interpreter& interpreter, const XERCESC_NS::DOMElement* content) { - std::stringstream ss; - ss << *content; - beforeExecutingContent(TAGNAME(content), DOMUtils::xPathForNode(content), ss.str()); + std::stringstream ss; + ss << *content; + beforeExecutingContent(TAGNAME(content), DOMUtils::xPathForNode(content), ss.str()); } void WrappedInterpreterMonitor::afterExecutingContent(Interpreter& interpreter, const XERCESC_NS::DOMElement* content) { - std::stringstream ss; - ss << *content; - afterExecutingContent(TAGNAME(content), DOMUtils::xPathForNode(content), ss.str()); + std::stringstream ss; + ss << *content; + afterExecutingContent(TAGNAME(content), DOMUtils::xPathForNode(content), ss.str()); } void WrappedInterpreterMonitor::beforeUninvoking(Interpreter& interpreter, const XERCESC_NS::DOMElement* invoker, const std::string& invokeid) { - std::stringstream ss; - ss << *invoker; - std::string invokeId; - if (invoker->getUserData(X("invokeid")) != NULL) { - invokeId = (char*)invoker->getUserData(X("invokeid")); - } - - beforeUninvoking(DOMUtils::xPathForNode(invoker), invokeId, ss.str()); + std::stringstream ss; + ss << *invoker; + std::string invokeId; + if (invoker->getUserData(X("invokeid")) != NULL) { + invokeId = (char*)invoker->getUserData(X("invokeid")); + } + + beforeUninvoking(DOMUtils::xPathForNode(invoker), invokeId, ss.str()); } void WrappedInterpreterMonitor::afterUninvoking(Interpreter& interpreter, const XERCESC_NS::DOMElement* invoker, const std::string& invokeid) { - std::stringstream ss; - ss << *invoker; - std::string invokeId; - if (invoker->getUserData(X("invokeid")) != NULL) { - invokeId = (char*)invoker->getUserData(X("invokeid")); - } - - afterUninvoking(DOMUtils::xPathForNode(invoker), invokeId, ss.str()); + std::stringstream ss; + ss << *invoker; + std::string invokeId; + if (invoker->getUserData(X("invokeid")) != NULL) { + invokeId = (char*)invoker->getUserData(X("invokeid")); + } + + afterUninvoking(DOMUtils::xPathForNode(invoker), invokeId, ss.str()); } void WrappedInterpreterMonitor::beforeTakingTransition(Interpreter& interpreter, const XERCESC_NS::DOMElement* transition) { - XERCESC_NS::DOMElement* sourceState = getSourceState(transition); - const XERCESC_NS::DOMElement* root = DOMUtils::getNearestAncestor(transition, "scxml"); - - std::list targetStates = getTargetStates(transition, root); - - std::stringstream ss; - ss << *transition; - - std::list targets; - for (auto t : targetStates) { - targets.push_back(ATTR_CAST(t, "id")); - } - - beforeTakingTransition(DOMUtils::xPathForNode(transition), ATTR_CAST(sourceState, "id"), targets, ss.str()); + XERCESC_NS::DOMElement* sourceState = getSourceState(transition); + const XERCESC_NS::DOMElement* root = DOMUtils::getNearestAncestor(transition, "scxml"); + + std::list targetStates = getTargetStates(transition, root); + + std::stringstream ss; + ss << *transition; + + std::list targets; + for (auto t : targetStates) { + targets.push_back(ATTR_CAST(t, "id")); + } + + beforeTakingTransition(DOMUtils::xPathForNode(transition), ATTR_CAST(sourceState, "id"), targets, ss.str()); } void WrappedInterpreterMonitor::afterTakingTransition(Interpreter& interpreter, const XERCESC_NS::DOMElement* transition) { - XERCESC_NS::DOMElement* sourceState = getSourceState(transition); - const XERCESC_NS::DOMElement* root = DOMUtils::getNearestAncestor(transition, "scxml"); - - std::list targetStates = getTargetStates(transition, root); - - std::stringstream ss; - ss << *transition; - - std::list targets; - for (auto t : targetStates) { - targets.push_back(ATTR_CAST(t, "id")); - } - - afterTakingTransition(DOMUtils::xPathForNode(transition), ATTR_CAST(sourceState, "id"), targets, ss.str()); + XERCESC_NS::DOMElement* sourceState = getSourceState(transition); + const XERCESC_NS::DOMElement* root = DOMUtils::getNearestAncestor(transition, "scxml"); + + std::list targetStates = getTargetStates(transition, root); + + std::stringstream ss; + ss << *transition; + + std::list targets; + for (auto t : targetStates) { + targets.push_back(ATTR_CAST(t, "id")); + } + + afterTakingTransition(DOMUtils::xPathForNode(transition), ATTR_CAST(sourceState, "id"), targets, ss.str()); } void WrappedInterpreterMonitor::beforeEnteringState(Interpreter& interpreter, const XERCESC_NS::DOMElement* state) { - std::stringstream ss; - ss << *state; - beforeEnteringState(ATTR(state, "id"), DOMUtils::xPathForNode(state), ss.str()); + std::stringstream ss; + ss << *state; + beforeEnteringState(ATTR(state, "id"), DOMUtils::xPathForNode(state), ss.str()); } void WrappedInterpreterMonitor::afterEnteringState(Interpreter& interpreter, const XERCESC_NS::DOMElement* state) { - std::stringstream ss; - ss << *state; - afterEnteringState(ATTR(state, "id"), DOMUtils::xPathForNode(state), ss.str()); + std::stringstream ss; + ss << *state; + afterEnteringState(ATTR(state, "id"), DOMUtils::xPathForNode(state), ss.str()); } void WrappedInterpreterMonitor::beforeInvoking(Interpreter& interpreter, const XERCESC_NS::DOMElement* invoker, const std::string& invokeid) { - std::stringstream ss; - ss << *invoker; - std::string invokeId; - if (invoker->getUserData(X("invokeid")) != NULL) { - invokeId = (char*)invoker->getUserData(X("invokeid")); - } - - beforeInvoking(DOMUtils::xPathForNode(invoker), invokeId, ss.str()); + std::stringstream ss; + ss << *invoker; + std::string invokeId; + if (invoker->getUserData(X("invokeid")) != NULL) { + invokeId = (char*)invoker->getUserData(X("invokeid")); + } + + beforeInvoking(DOMUtils::xPathForNode(invoker), invokeId, ss.str()); } void WrappedInterpreterMonitor::afterInvoking(Interpreter& interpreter, const XERCESC_NS::DOMElement* invoker, const std::string& invokeid) { - std::stringstream ss; - ss << *invoker; - std::string invokeId; - if (invoker->getUserData(X("invokeid")) != NULL) { - invokeId = (char*)invoker->getUserData(X("invokeid")); - } - - afterInvoking(DOMUtils::xPathForNode(invoker), invokeId, ss.str()); + std::stringstream ss; + ss << *invoker; + std::string invokeId; + if (invoker->getUserData(X("invokeid")) != NULL) { + invokeId = (char*)invoker->getUserData(X("invokeid")); + } + + afterInvoking(DOMUtils::xPathForNode(invoker), invokeId, ss.str()); } } \ No newline at end of file diff --git a/src/bindings/swig/wrapped/WrappedInterpreterMonitor.h b/src/bindings/swig/wrapped/WrappedInterpreterMonitor.h index e05dad2..697a420 100644 --- a/src/bindings/swig/wrapped/WrappedInterpreterMonitor.h +++ b/src/bindings/swig/wrapped/WrappedInterpreterMonitor.h @@ -34,7 +34,7 @@ // forward declare namespace XERCESC_NS { - class DOMElement; +class DOMElement; } namespace uscxml { @@ -44,100 +44,100 @@ public: WrappedInterpreterMonitor(); virtual ~WrappedInterpreterMonitor(); - virtual void beforeProcessingEvent(Interpreter& interpreter, const Event& event) {} - virtual void beforeMicroStep(Interpreter& interpreter) {} + virtual void beforeProcessingEvent(Interpreter& interpreter, const Event& event) {} + virtual void beforeMicroStep(Interpreter& interpreter) {} - void beforeExitingState(Interpreter& interpreter, const XERCESC_NS::DOMElement* state); - virtual void beforeExitingState(const std::string& stateId, + void beforeExitingState(Interpreter& interpreter, const XERCESC_NS::DOMElement* state); + virtual void beforeExitingState(const std::string& stateId, const std::string& xpath, const std::string& stateXML) {} - void afterExitingState(Interpreter& interpreter, const XERCESC_NS::DOMElement* state); - virtual void afterExitingState(const std::string& stateId, - const std::string& xpath, - const std::string& stateXML) {} + void afterExitingState(Interpreter& interpreter, const XERCESC_NS::DOMElement* state); + virtual void afterExitingState(const std::string& stateId, + const std::string& xpath, + const std::string& stateXML) {} - void beforeExecutingContent(Interpreter& interpreter, const XERCESC_NS::DOMElement* content); - virtual void beforeExecutingContent(const std::string& tagName, + void beforeExecutingContent(Interpreter& interpreter, const XERCESC_NS::DOMElement* content); + virtual void beforeExecutingContent(const std::string& tagName, const std::string& xpath, const std::string& contentXML) {} - void afterExecutingContent(Interpreter& interpreter, const XERCESC_NS::DOMElement* content); - virtual void afterExecutingContent(const std::string& tagName, + void afterExecutingContent(Interpreter& interpreter, const XERCESC_NS::DOMElement* content); + virtual void afterExecutingContent(const std::string& tagName, const std::string& xpath, const std::string& contentXML) {} void beforeUninvoking(Interpreter& interpreter, - const XERCESC_NS::DOMElement* invoker, - const std::string& invokeid); + const XERCESC_NS::DOMElement* invoker, + const std::string& invokeid); virtual void beforeUninvoking(const std::string& xpath, const std::string& invokeid, const std::string& invokerXML) {} void afterUninvoking(Interpreter& interpreter, - const XERCESC_NS::DOMElement* invoker, - const std::string& invokeid); - virtual void afterUninvoking(const std::string& xpath, + const XERCESC_NS::DOMElement* invoker, + const std::string& invokeid); + virtual void afterUninvoking(const std::string& xpath, const std::string& invokeid, const std::string& invokerXML) {} - void beforeTakingTransition(Interpreter& interpreter, - const XERCESC_NS::DOMElement* transition); + void beforeTakingTransition(Interpreter& interpreter, + const XERCESC_NS::DOMElement* transition); virtual void beforeTakingTransition(const std::string& xpath, const std::string& source, const std::list& targets, const std::string& transitionXML) {} - void afterTakingTransition(Interpreter& interpreter, - const XERCESC_NS::DOMElement* transition); - virtual void afterTakingTransition(const std::string& xpath, + void afterTakingTransition(Interpreter& interpreter, + const XERCESC_NS::DOMElement* transition); + virtual void afterTakingTransition(const std::string& xpath, const std::string& source, const std::list& targets, const std::string& transitionXML) {} - void beforeEnteringState(Interpreter& interpreter, - const XERCESC_NS::DOMElement* state); - virtual void beforeEnteringState(const std::string& stateId, + void beforeEnteringState(Interpreter& interpreter, + const XERCESC_NS::DOMElement* state); + virtual void beforeEnteringState(const std::string& stateId, const std::string& xpath, const std::string& stateXML) {} - void afterEnteringState(Interpreter& interpreter, - const XERCESC_NS::DOMElement* state); - virtual void afterEnteringState(const std::string& stateId, + void afterEnteringState(Interpreter& interpreter, + const XERCESC_NS::DOMElement* state); + virtual void afterEnteringState(const std::string& stateId, const std::string& xpath, const std::string& stateXML) {} void beforeInvoking(Interpreter& interpreter, - const XERCESC_NS::DOMElement* invoker, - const std::string& invokeid); - virtual void beforeInvoking(const std::string& xpath, + const XERCESC_NS::DOMElement* invoker, + const std::string& invokeid); + virtual void beforeInvoking(const std::string& xpath, const std::string& invokeid, const std::string& invokerXML) {} - void afterInvoking(Interpreter& interpreter, - const XERCESC_NS::DOMElement* invoker, - const std::string& invokeid); - virtual void afterInvoking(const std::string& xpath, + void afterInvoking(Interpreter& interpreter, + const XERCESC_NS::DOMElement* invoker, + const std::string& invokeid); + virtual void afterInvoking(const std::string& xpath, const std::string& invokeid, const std::string& invokerXML) {} - virtual void afterMicroStep(Interpreter& interpreter) {} - virtual void onStableConfiguration(Interpreter& interpreter) {} - - virtual void beforeCompletion(Interpreter& interpreter) {} - virtual void afterCompletion(Interpreter& interpreter) {} + virtual void afterMicroStep(Interpreter& interpreter) {} + virtual void onStableConfiguration(Interpreter& interpreter) {} + + virtual void beforeCompletion(Interpreter& interpreter) {} + virtual void afterCompletion(Interpreter& interpreter) {} virtual void reportIssue(Interpreter& interpreter, - const InterpreterIssue& issue) {} + const InterpreterIssue& issue) {} }; } diff --git a/src/bindings/swig/wrapped/WrappedInvoker.cpp b/src/bindings/swig/wrapped/WrappedInvoker.cpp index ba76420..407323d 100644 --- a/src/bindings/swig/wrapped/WrappedInvoker.cpp +++ b/src/bindings/swig/wrapped/WrappedInvoker.cpp @@ -22,7 +22,7 @@ namespace uscxml { WrappedInvoker::WrappedInvoker(InterpreterImpl* interpreter) { - _interpreter = interpreter; + _interpreter = interpreter; } WrappedInvoker::~WrappedInvoker() {} diff --git a/src/bindings/swig/wrapped/WrappedInvoker.h b/src/bindings/swig/wrapped/WrappedInvoker.h index 3eb4a22..bb5d1ba 100644 --- a/src/bindings/swig/wrapped/WrappedInvoker.h +++ b/src/bindings/swig/wrapped/WrappedInvoker.h @@ -33,7 +33,7 @@ // forward declare namespace XERCESC_NS { - class DOMElement; +class DOMElement; } namespace uscxml { @@ -42,37 +42,37 @@ class WrappedInvoker : public InvokerImpl { public: WrappedInvoker(InterpreterImpl* interpreter); virtual ~WrappedInvoker(); - - virtual std::list getNames() { - return std::list(); - }; - - virtual std::shared_ptr create(InterpreterImpl* interpreter) { - std::shared_ptr inv = std::shared_ptr(new WrappedInvoker(interpreter)); - return inv; - } - virtual void invoke(const std::string& source, const Event& invokeEvent) {} - virtual void uninvoke() {} - - virtual void eventFromSCXML(const Event& event) {} - - virtual XERCESC_NS::DOMElement* getFinalize() { - return _finalize; - } - virtual void setFinalize(XERCESC_NS::DOMElement* finalize) { - _finalize = finalize; - } - virtual void setInvokeId(const std::string& invokeId) { - _invokeId = invokeId; - } - - virtual Data getDataModelVariables() { - return Data(); - } - - void eventToSCXML(Event& event, const std::string& type, const std::string& invokeId, bool internal = false) { - - } + + virtual std::list getNames() { + return std::list(); + }; + + virtual std::shared_ptr create(InterpreterImpl* interpreter) { + std::shared_ptr inv = std::shared_ptr(new WrappedInvoker(interpreter)); + return inv; + } + virtual void invoke(const std::string& source, const Event& invokeEvent) {} + virtual void uninvoke() {} + + virtual void eventFromSCXML(const Event& event) {} + + virtual XERCESC_NS::DOMElement* getFinalize() { + return _finalize; + } + virtual void setFinalize(XERCESC_NS::DOMElement* finalize) { + _finalize = finalize; + } + virtual void setInvokeId(const std::string& invokeId) { + _invokeId = invokeId; + } + + virtual Data getDataModelVariables() { + return Data(); + } + + void eventToSCXML(Event& event, const std::string& type, const std::string& invokeId, bool internal = false) { + + } private: InterpreterImpl* _interpreter; diff --git a/src/uscxml/Interpreter.cpp b/src/uscxml/Interpreter.cpp index 1d348fd..1e8c931 100644 --- a/src/uscxml/Interpreter.cpp +++ b/src/uscxml/Interpreter.cpp @@ -219,7 +219,7 @@ void Interpreter::setActionLanguage(ActionLanguage actionLanguage) { } void Interpreter::setFactory(Factory* factory) { - return _impl->setFactory(factory); + return _impl->setFactory(factory); } void Interpreter::addMonitor(InterpreterMonitor* monitor) { @@ -227,7 +227,7 @@ void Interpreter::addMonitor(InterpreterMonitor* monitor) { } void Interpreter::removeMonitor(InterpreterMonitor* monitor) { - return _impl->removeMonitor(monitor); + return _impl->removeMonitor(monitor); } std::list Interpreter::validate() { diff --git a/src/uscxml/Interpreter.h b/src/uscxml/Interpreter.h index f87053f..6c60350 100644 --- a/src/uscxml/Interpreter.h +++ b/src/uscxml/Interpreter.h @@ -118,7 +118,7 @@ public: */ PIMPL_OPERATORS(Interpreter); - /** + /** * Advance the state-machine by a single microstep and return. * * This is the central function to drive the state machine. Calling step() @@ -179,22 +179,22 @@ public: */ void setActionLanguage(ActionLanguage actionLanguage); - /** - * Provide a custom Factory to instantiate dynamic instances for this and invoked state-chart instances. - */ - void setFactory(Factory* factory); + /** + * Provide a custom Factory to instantiate dynamic instances for this and invoked state-chart instances. + */ + void setFactory(Factory* factory); /** * Attach a monitor to make more details of the interpreter observable. */ - void addMonitor(InterpreterMonitor* monitor); - - /** - * Remove a monitor that was attached previously. - */ - void removeMonitor(InterpreterMonitor* monitor); + void addMonitor(InterpreterMonitor* monitor); + + /** + * Remove a monitor that was attached previously. + */ + void removeMonitor(InterpreterMonitor* monitor); + - /** * Return the actual implementation of the Interperter. */ diff --git a/src/uscxml/debug/Breakpoint.cpp b/src/uscxml/debug/Breakpoint.cpp index 3287075..7b9d5c9 100644 --- a/src/uscxml/debug/Breakpoint.cpp +++ b/src/uscxml/debug/Breakpoint.cpp @@ -244,7 +244,7 @@ bool Breakpoint::matches(Interpreter interpreter, const Breakpoint& other) const return InterpreterImpl::isMember(other.element, nodes); } #endif - + if(transSourceId.length() > 0 && transSourceId != other.transSourceId) { return false; } @@ -255,7 +255,7 @@ bool Breakpoint::matches(Interpreter interpreter, const Breakpoint& other) const if (condition.length() > 0) { try { - interpreter.getImpl()->isTrue(condition); + interpreter.getImpl()->isTrue(condition); } catch (...) { return false; } diff --git a/src/uscxml/debug/Breakpoint.h b/src/uscxml/debug/Breakpoint.h index 3809663..feaf221 100644 --- a/src/uscxml/debug/Breakpoint.h +++ b/src/uscxml/debug/Breakpoint.h @@ -28,7 +28,7 @@ // forward declare namespace XERCESC_NS { - class DOMElement; +class DOMElement; } namespace uscxml { @@ -76,7 +76,7 @@ public: Subject subject; Action action; - const XERCESC_NS::DOMElement* element = NULL; + const XERCESC_NS::DOMElement* element = NULL; std::string invokeId; std::string invokeType; diff --git a/src/uscxml/debug/DebugSession.cpp b/src/uscxml/debug/DebugSession.cpp index 60dcdfb..4d64443 100644 --- a/src/uscxml/debug/DebugSession.cpp +++ b/src/uscxml/debug/DebugSession.cpp @@ -74,21 +74,21 @@ void DebugSession::checkBreakpoints(const std::list qualifiedBreakpo void DebugSession::breakExecution(Data replyData) { std::lock_guard lock(_mutex); - std::list configuration = _interpreter.getConfiguration(); - for (auto state : configuration) { - if (HAS_ATTR(state, "id")) { - replyData.compound["activeStates"].array.push_back(Data(ATTR(state, "id"), Data::VERBATIM)); - if (isAtomic(state)) { - replyData.compound["basicStates"].array.push_back(Data(ATTR(state, "id"), Data::VERBATIM)); - } - } - } + std::list configuration = _interpreter.getConfiguration(); + for (auto state : configuration) { + if (HAS_ATTR(state, "id")) { + replyData.compound["activeStates"].array.push_back(Data(ATTR(state, "id"), Data::VERBATIM)); + if (isAtomic(state)) { + replyData.compound["basicStates"].array.push_back(Data(ATTR(state, "id"), Data::VERBATIM)); + } + } + } replyData.compound["replyType"] = Data("breakpoint", Data::VERBATIM); _debugger->pushData(shared_from_this(), replyData); - - // wait for resume from the client - _resumeCond.wait(_mutex); + + // wait for resume from the client + _resumeCond.wait(_mutex); } Data DebugSession::debugPrepare(const Data& data) { @@ -104,23 +104,23 @@ Data DebugSession::debugPrepare(const Data& data) { _isAttached = false; - try { - if (data.hasKey("xml")) { - _interpreter = Interpreter::fromXML(data.at("xml").atom, (data.hasKey("url") ? data.at("url").atom : "")); - } else if (data.hasKey("url")) { - _interpreter = Interpreter::fromURL(data.at("url").atom); - } else { - _interpreter = Interpreter(); - } - } catch(ErrorEvent e) { - std::cerr << e; - } catch(...) {} - + try { + if (data.hasKey("xml")) { + _interpreter = Interpreter::fromXML(data.at("xml").atom, (data.hasKey("url") ? data.at("url").atom : "")); + } else if (data.hasKey("url")) { + _interpreter = Interpreter::fromURL(data.at("url").atom); + } else { + _interpreter = Interpreter(); + } + } catch(ErrorEvent e) { + std::cerr << e; + } catch(...) {} + if (_interpreter) { // register ourself as a monitor _interpreter.addMonitor(_debugger); _debugger->attachSession(_interpreter.getImpl().get(), shared_from_this()); - + replyData.compound["status"] = Data("success", Data::VERBATIM); } else { replyData.compound["status"] = Data("failure", Data::VERBATIM); @@ -143,8 +143,8 @@ Data DebugSession::debugAttach(const Data& data) { bool interpreterFound = false; // find interpreter for sessionid - std::map > instances = InterpreterImpl::getInstances(); - for (auto weakInstance : instances) { + std::map > instances = InterpreterImpl::getInstances(); + for (auto weakInstance : instances) { std::shared_ptr instance = weakInstance.second.lock(); if (instance && instance->getSessionId() == interpreterId) { @@ -185,8 +185,8 @@ Data DebugSession::debugStart(const Data& data) { replyData.compound["reason"] = Data("No interpreter attached or loaded", Data::VERBATIM); replyData.compound["status"] = Data("failure", Data::VERBATIM); } else { - _isRunning = true; - _interpreterThread = new std::thread(DebugSession::run, this); + _isRunning = true; + _interpreterThread = new std::thread(DebugSession::run, this); replyData.compound["status"] = Data("success", Data::VERBATIM); } @@ -194,28 +194,28 @@ Data DebugSession::debugStart(const Data& data) { } void DebugSession::run(void* instance) { - DebugSession* INSTANCE = (DebugSession*)instance; - + DebugSession* INSTANCE = (DebugSession*)instance; + #ifdef APPLE - std::string threadName; - threadName += "uscxml::"; - threadName += (INSTANCE->_interpreter.getImpl()->_name.size() > 0 ? INSTANCE->_interpreter.getImpl()->_name : "anon"); - threadName += ".debug"; - - pthread_setname_np(threadName.c_str()); + std::string threadName; + threadName += "uscxml::"; + threadName += (INSTANCE->_interpreter.getImpl()->_name.size() > 0 ? INSTANCE->_interpreter.getImpl()->_name : "anon"); + threadName += ".debug"; + + pthread_setname_np(threadName.c_str()); #endif - - InterpreterState state = USCXML_UNDEF; - while(state != USCXML_FINISHED && INSTANCE->_isRunning) { - state = INSTANCE->_interpreter.step(); - - // if (!INSTANCE->_isStarted) { - // // we have been cancelled - // INSTANCE->_isActive = false; - // return; - // } - } - LOG(DEBUG) << "done"; + + InterpreterState state = USCXML_UNDEF; + while(state != USCXML_FINISHED && INSTANCE->_isRunning) { + state = INSTANCE->_interpreter.step(); + + // if (!INSTANCE->_isStarted) { + // // we have been cancelled + // INSTANCE->_isActive = false; + // return; + // } + } + LOG(DEBUG) << "done"; } Data DebugSession::debugStop(const Data& data) { @@ -226,11 +226,11 @@ Data DebugSession::debugStop(const Data& data) { _debugger->detachSession(_interpreter.getImpl().get()); } - if (_isRunning && _interpreterThread != NULL) { - _isRunning = false; - _interpreterThread->join(); - delete(_interpreterThread); - } + if (_isRunning && _interpreterThread != NULL) { + _isRunning = false; + _interpreterThread->join(); + delete(_interpreterThread); + } // unblock _resumeCond.notify_all(); @@ -252,11 +252,11 @@ Data DebugSession::debugStep(const Data& data) { Data replyData; if (_interpreter) { // register ourself as a monitor - if (!_isRunning) { - _isRunning = true; - _interpreterThread = new std::thread(DebugSession::run, this); + if (!_isRunning) { + _isRunning = true; + _interpreterThread = new std::thread(DebugSession::run, this); - } + } replyData.compound["status"] = Data("success", Data::VERBATIM); } else { @@ -294,19 +294,19 @@ Data DebugSession::skipToBreakPoint(const Data& data) { std::lock_guard lock(_mutex); _skipTo = Breakpoint(data); - Data replyData; - - if (_interpreter) { - // register ourself as a monitor - if (!_isRunning) { - _isRunning = true; - _interpreterThread = new std::thread(DebugSession::run, this); - } - - replyData.compound["status"] = Data("success", Data::VERBATIM); - } else { - replyData.compound["status"] = Data("failure", Data::VERBATIM); - } + Data replyData; + + if (_interpreter) { + // register ourself as a monitor + if (!_isRunning) { + _isRunning = true; + _interpreterThread = new std::thread(DebugSession::run, this); + } + + replyData.compound["status"] = Data("success", Data::VERBATIM); + } else { + replyData.compound["status"] = Data("failure", Data::VERBATIM); + } _resumeCond.notify_one(); return replyData; diff --git a/src/uscxml/debug/DebugSession.h b/src/uscxml/debug/DebugSession.h index c4f2564..fbfd065 100644 --- a/src/uscxml/debug/DebugSession.h +++ b/src/uscxml/debug/DebugSession.h @@ -34,8 +34,8 @@ class Debugger; class USCXML_API DebugSession : public std::enable_shared_from_this { public: DebugSession() { - _isRunning = false; - _isStepping = false; + _isRunning = false; + _isStepping = false; _isAttached = false; _breakpointsEnabled = true; _markedForDeletion = false; @@ -88,9 +88,9 @@ protected: std::recursive_mutex _runMutex; std::recursive_mutex _mutex; - std::thread* _interpreterThread = NULL; - bool _isRunning; - static void run(void* instance); + std::thread* _interpreterThread = NULL; + bool _isRunning; + static void run(void* instance); bool _markedForDeletion; Debugger* _debugger; @@ -98,7 +98,7 @@ protected: std::set _breakPoints; Breakpoint _skipTo; - friend class Debugger; + friend class Debugger; }; diff --git a/src/uscxml/debug/Debugger.cpp b/src/uscxml/debug/Debugger.cpp index 1f13e40..9478927 100644 --- a/src/uscxml/debug/Debugger.cpp +++ b/src/uscxml/debug/Debugger.cpp @@ -25,7 +25,7 @@ namespace uscxml { void Debugger::afterCompletion(Interpreter& interpreter) { - InterpreterImpl* impl = interpreter.getImpl().get(); + InterpreterImpl* impl = interpreter.getImpl().get(); std::shared_ptr session = getSession(impl); if (!session) return; @@ -72,9 +72,9 @@ std::list Debugger::getQualifiedTransBreakpoints(InterpreterImpl* im std::list breakpoints; XERCESC_NS::DOMElement* source = getSourceState(transition); - std::list targets = getTargetStates(transition, impl->_scxml); + std::list targets = getTargetStates(transition, impl->_scxml); - for (auto target : targets) { + for (auto target : targets) { Breakpoint bp = breakpointTemplate; // copy base as template bp.element = transition; @@ -143,9 +143,9 @@ void Debugger::handleExecutable(Interpreter& interpreter, std::shared_ptr session = getSession(interpreter.getImpl().get()); if (!session) return; - if (!session->_isRunning) - return; - + if (!session->_isRunning) + return; + std::list breakpoints; Breakpoint breakpoint; @@ -160,12 +160,12 @@ void Debugger::handleExecutable(Interpreter& interpreter, } void Debugger::handleEvent(Interpreter& interpreter, const Event& event, Breakpoint::When when) { - InterpreterImpl* impl = interpreter.getImpl().get(); - std::shared_ptr session = getSession(impl); - if (!session) - return; - if (!session->_isRunning) - return; + InterpreterImpl* impl = interpreter.getImpl().get(); + std::shared_ptr session = getSession(impl); + if (!session) + return; + if (!session->_isRunning) + return; std::list breakpoints; @@ -180,12 +180,12 @@ void Debugger::handleEvent(Interpreter& interpreter, const Event& event, Breakpo } void Debugger::handleStable(Interpreter& interpreter, Breakpoint::When when) { - InterpreterImpl* impl = interpreter.getImpl().get(); - std::shared_ptr session = getSession(impl); - if (!session) - return; - if (!session->_isRunning) - return; + InterpreterImpl* impl = interpreter.getImpl().get(); + std::shared_ptr session = getSession(impl); + if (!session) + return; + if (!session->_isRunning) + return; std::list breakpoints; @@ -198,12 +198,12 @@ void Debugger::handleStable(Interpreter& interpreter, Breakpoint::When when) { } void Debugger::handleMicrostep(Interpreter& interpreter, Breakpoint::When when) { - InterpreterImpl* impl = interpreter.getImpl().get(); - std::shared_ptr session = getSession(impl); - if (!session) - return; - if (!session->_isRunning) - return; + InterpreterImpl* impl = interpreter.getImpl().get(); + std::shared_ptr session = getSession(impl); + if (!session) + return; + if (!session->_isRunning) + return; std::list breakpoints; @@ -216,12 +216,12 @@ void Debugger::handleMicrostep(Interpreter& interpreter, Breakpoint::When when) } void Debugger::handleTransition(Interpreter& interpreter, const XERCESC_NS::DOMElement* transition, Breakpoint::When when) { - InterpreterImpl* impl = interpreter.getImpl().get(); - std::shared_ptr session = getSession(impl); - if (!session) - return; - if (!session->_isRunning) - return; + InterpreterImpl* impl = interpreter.getImpl().get(); + std::shared_ptr session = getSession(impl); + if (!session) + return; + if (!session->_isRunning) + return; Breakpoint breakpointTemplate; breakpointTemplate.when = when; @@ -230,12 +230,12 @@ void Debugger::handleTransition(Interpreter& interpreter, const XERCESC_NS::DOME } void Debugger::handleState(Interpreter& interpreter, const XERCESC_NS::DOMElement* state, Breakpoint::When when, Breakpoint::Action action) { - InterpreterImpl* impl = interpreter.getImpl().get(); - std::shared_ptr session = getSession(impl); - if (!session) - return; - if (!session->_isRunning) - return; + InterpreterImpl* impl = interpreter.getImpl().get(); + std::shared_ptr session = getSession(impl); + if (!session) + return; + if (!session->_isRunning) + return; Breakpoint breakpointTemplate; breakpointTemplate.when = when; @@ -246,12 +246,12 @@ void Debugger::handleState(Interpreter& interpreter, const XERCESC_NS::DOMElemen } void Debugger::handleInvoke(Interpreter& interpreter, const XERCESC_NS::DOMElement* invokeElem, const std::string& invokeId, Breakpoint::When when, Breakpoint::Action action) { - InterpreterImpl* impl = interpreter.getImpl().get(); - std::shared_ptr session = getSession(impl); - if (!session) - return; - if (!session->_isRunning) - return; + InterpreterImpl* impl = interpreter.getImpl().get(); + std::shared_ptr session = getSession(impl); + if (!session) + return; + if (!session->_isRunning) + return; Breakpoint breakpointTemplate; breakpointTemplate.when = when; diff --git a/src/uscxml/debug/Debugger.h b/src/uscxml/debug/Debugger.h index 4b564cb..d69e6f6 100644 --- a/src/uscxml/debug/Debugger.h +++ b/src/uscxml/debug/Debugger.h @@ -55,24 +55,24 @@ public: virtual void pushData(std::shared_ptr session, Data pushData) = 0; // InterpreterMonitor - virtual void beforeProcessingEvent(Interpreter& interpreter, const Event& event); - virtual void beforeMicroStep(Interpreter& interpreter); - virtual void beforeExitingState(Interpreter& interpreter, const XERCESC_NS::DOMElement* state); - virtual void afterExitingState(Interpreter& interpreter, const XERCESC_NS::DOMElement* state); - virtual void beforeExecutingContent(Interpreter& interpreter, const XERCESC_NS::DOMElement* execContent); - virtual void afterExecutingContent(Interpreter& interpreter, const XERCESC_NS::DOMElement* execContent); - virtual void beforeUninvoking(Interpreter& interpreter, const XERCESC_NS::DOMElement* invokeElem, const std::string& invokeid); - virtual void afterUninvoking(Interpreter& interpreter, const XERCESC_NS::DOMElement* invokeElem, const std::string& invokeid); - virtual void beforeTakingTransition(Interpreter& interpreter, const XERCESC_NS::DOMElement* transition); - virtual void afterTakingTransition(Interpreter& interpreter, const XERCESC_NS::DOMElement* transition); - virtual void beforeEnteringState(Interpreter& interpreter, const XERCESC_NS::DOMElement* state); - virtual void afterEnteringState(Interpreter& interpreter, const XERCESC_NS::DOMElement* state); - virtual void beforeInvoking(Interpreter& interpreter, const XERCESC_NS::DOMElement* invokeElem, const std::string& invokeid); - virtual void afterInvoking(Interpreter& interpreter, const XERCESC_NS::DOMElement* invokeElem, const std::string& invokeid); - virtual void afterMicroStep(Interpreter& interpreter); - virtual void onStableConfiguration(Interpreter& interpreter); - virtual void beforeCompletion(Interpreter& interpreter); - virtual void afterCompletion(Interpreter& interpreter); + virtual void beforeProcessingEvent(Interpreter& interpreter, const Event& event); + virtual void beforeMicroStep(Interpreter& interpreter); + virtual void beforeExitingState(Interpreter& interpreter, const XERCESC_NS::DOMElement* state); + virtual void afterExitingState(Interpreter& interpreter, const XERCESC_NS::DOMElement* state); + virtual void beforeExecutingContent(Interpreter& interpreter, const XERCESC_NS::DOMElement* execContent); + virtual void afterExecutingContent(Interpreter& interpreter, const XERCESC_NS::DOMElement* execContent); + virtual void beforeUninvoking(Interpreter& interpreter, const XERCESC_NS::DOMElement* invokeElem, const std::string& invokeid); + virtual void afterUninvoking(Interpreter& interpreter, const XERCESC_NS::DOMElement* invokeElem, const std::string& invokeid); + virtual void beforeTakingTransition(Interpreter& interpreter, const XERCESC_NS::DOMElement* transition); + virtual void afterTakingTransition(Interpreter& interpreter, const XERCESC_NS::DOMElement* transition); + virtual void beforeEnteringState(Interpreter& interpreter, const XERCESC_NS::DOMElement* state); + virtual void afterEnteringState(Interpreter& interpreter, const XERCESC_NS::DOMElement* state); + virtual void beforeInvoking(Interpreter& interpreter, const XERCESC_NS::DOMElement* invokeElem, const std::string& invokeid); + virtual void afterInvoking(Interpreter& interpreter, const XERCESC_NS::DOMElement* invokeElem, const std::string& invokeid); + virtual void afterMicroStep(Interpreter& interpreter); + virtual void onStableConfiguration(Interpreter& interpreter); + virtual void beforeCompletion(Interpreter& interpreter); + virtual void afterCompletion(Interpreter& interpreter); protected: @@ -95,19 +95,19 @@ protected: void handleMicrostep(Interpreter& interpreter, Breakpoint::When when); void handleEvent(Interpreter& interpreter, const Event& event, Breakpoint::When when); - std::list getQualifiedTransBreakpoints(InterpreterImpl* impl, - const XERCESC_NS::DOMElement* transition, - Breakpoint breakpointTemplate); - std::list getQualifiedStateBreakpoints(InterpreterImpl* impl, - const XERCESC_NS::DOMElement* state, - Breakpoint breakpointTemplate); - std::list getQualifiedInvokeBreakpoints(InterpreterImpl* impl, - const XERCESC_NS::DOMElement* invokeElem, - const std::string invokeId, - Breakpoint breakpointTemplate); + std::list getQualifiedTransBreakpoints(InterpreterImpl* impl, + const XERCESC_NS::DOMElement* transition, + Breakpoint breakpointTemplate); + std::list getQualifiedStateBreakpoints(InterpreterImpl* impl, + const XERCESC_NS::DOMElement* state, + Breakpoint breakpointTemplate); + std::list getQualifiedInvokeBreakpoints(InterpreterImpl* impl, + const XERCESC_NS::DOMElement* invokeElem, + const std::string invokeId, + Breakpoint breakpointTemplate); std::recursive_mutex _sessionMutex; - /// @todo: We ought to change form InterpreterImpl to Interpreter everywhere + /// @todo: We ought to change form InterpreterImpl to Interpreter everywhere std::map > _sessionForInterpreter; }; diff --git a/src/uscxml/debug/DebuggerServlet.cpp b/src/uscxml/debug/DebuggerServlet.cpp index 25df9dd..34c1eca 100644 --- a/src/uscxml/debug/DebuggerServlet.cpp +++ b/src/uscxml/debug/DebuggerServlet.cpp @@ -219,10 +219,10 @@ void DebuggerServlet::processDisconnect(const HTTPServer::Request& request) { void DebuggerServlet::processListSessions(const HTTPServer::Request& request) { Data replyData; - std::map > instances = InterpreterImpl::getInstances(); - for (auto weakInstance : instances) { + std::map > instances = InterpreterImpl::getInstances(); + for (auto weakInstance : instances) { - std::shared_ptr instance = weakInstance.second.lock(); + std::shared_ptr instance = weakInstance.second.lock(); if (instance) { Data sessionData; sessionData.compound["name"] = Data(instance->getName(), Data::VERBATIM); diff --git a/src/uscxml/debug/DebuggerServlet.h b/src/uscxml/debug/DebuggerServlet.h index 2ed1879..a1f18e3 100644 --- a/src/uscxml/debug/DebuggerServlet.h +++ b/src/uscxml/debug/DebuggerServlet.h @@ -34,7 +34,7 @@ public: class LogMessage : public Data { public: #if 0 - LogMessage(google::LogSeverity severity, const char* full_filename, + LogMessage(google::LogSeverity severity, const char* full_filename, const char* base_filename, int line, const struct ::tm* tm_time, std::string message, std::string formatted) { @@ -86,13 +86,13 @@ public: // void processPoll(const HTTPServer::Request& request); // Logsink - /** + /** virtual void send(google::LogSeverity severity, const char* full_filename, const char* base_filename, int line, const struct ::tm* tm_time, const char* message, size_t message_len); -*/ - void handle(const el::LogDispatchData* data); + */ + void handle(const el::LogDispatchData* data); protected: void serverPushData(std::shared_ptr); diff --git a/src/uscxml/debug/InterpreterIssue.cpp b/src/uscxml/debug/InterpreterIssue.cpp index df2d125..90e06b4 100644 --- a/src/uscxml/debug/InterpreterIssue.cpp +++ b/src/uscxml/debug/InterpreterIssue.cpp @@ -39,7 +39,7 @@ InterpreterIssue::InterpreterIssue(const std::string& msg, DOMNode* node, IssueS // find all elements in the SCXML namespace in one traversal void assembleNodeSets(const std::string nsPrefix, DOMElement* node, std::map >& sets) { - for (auto childElem = node->getFirstElementChild(); childElem; childElem = childElem->getNextElementSibling()) { + for (auto childElem = node->getFirstElementChild(); childElem; childElem = childElem->getNextElementSibling()) { if (TAGNAME(childElem).find(nsPrefix) == 0) { // correct namespace, insert via localname @@ -57,7 +57,7 @@ std::list > getAllConfigurations(const DOMElement* std::cout << *root; - for (auto childElem = root->getFirstElementChild(); childElem; childElem = childElem->getNextElementSibling()) { + for (auto childElem = root->getFirstElementChild(); childElem; childElem = childElem->getNextElementSibling()) { std::cout << *childElem; if (XMLString::compareIString(childElem->getTagName(), X(nsPrefix + "state")) == 0 || diff --git a/src/uscxml/interpreter/BasicContentExecutor.cpp b/src/uscxml/interpreter/BasicContentExecutor.cpp index f85e2b8..9f58b46 100644 --- a/src/uscxml/interpreter/BasicContentExecutor.cpp +++ b/src/uscxml/interpreter/BasicContentExecutor.cpp @@ -210,7 +210,7 @@ void BasicContentExecutor::processCancel(XERCESC_NS::DOMElement* content) { void BasicContentExecutor::processIf(XERCESC_NS::DOMElement* content) { bool blockIsTrue = _callbacks->isTrue(ATTR(content, "cond")); - for (auto childElem = content->getFirstElementChild(); childElem; childElem = childElem->getNextElementSibling()) { + for (auto childElem = content->getFirstElementChild(); childElem; childElem = childElem->getNextElementSibling()) { if (iequals(TAGNAME(childElem), XML_PREFIX(content).str() + "elseif")) { if (blockIsTrue) { // last block was true, break here @@ -252,7 +252,7 @@ void BasicContentExecutor::processForeach(XERCESC_NS::DOMElement* content) { for (uint32_t iteration = 0; iteration < iterations; iteration++) { _callbacks->setForeach(item, array, index, iteration); - for (auto childElem = content->getFirstElementChild(); childElem; childElem = childElem->getNextElementSibling()) { + for (auto childElem = content->getFirstElementChild(); childElem; childElem = childElem->getNextElementSibling()) { process(childElem, XML_PREFIX(content)); } } @@ -285,7 +285,7 @@ void BasicContentExecutor::process(XERCESC_NS::DOMElement* block, const X& xmlPr iequals(tagName, xmlPrefix.str() + "transition")) { try { - for (auto childElem = block->getFirstElementChild(); childElem; childElem = childElem->getNextElementSibling()) { + for (auto childElem = block->getFirstElementChild(); childElem; childElem = childElem->getNextElementSibling()) { // process any child eleents process(childElem, xmlPrefix); } @@ -404,7 +404,7 @@ void BasicContentExecutor::invoke(XERCESC_NS::DOMElement* element) { _callbacks->assign(ATTR(element, "idlocation"), Data(invokeEvent.invokeid, Data::VERBATIM)); } } - + // we need the invokeid to uninvoke char* invokeId = (char*)malloc(invokeEvent.invokeid.size() + 1); memcpy(invokeId, invokeEvent.invokeid.c_str(), invokeEvent.invokeid.size()); @@ -477,7 +477,7 @@ void BasicContentExecutor::uninvoke(XERCESC_NS::DOMElement* invoke) { _callbacks->uninvoke(invokeId); USCXML_MONITOR_CALLBACK2(_callbacks->getMonitors(), afterUninvoking, invoke, invokeId); - invoke->setUserData(X("invokeid"), NULL, NULL); + invoke->setUserData(X("invokeid"), NULL, NULL); free(invokeId); } @@ -558,7 +558,7 @@ Data BasicContentExecutor::elementAsData(XERCESC_NS::DOMElement* element) { if (HAS_ATTR(element, "expr")) { // return _callbacks->evalAsData(ATTR(element, "expr")); #if 0 - if (LOCALNAME(element) == "content") { + if (LOCALNAME(element) == "content") { // test 528 return _callbacks->evalAsData(ATTR(element, "expr")); } else { @@ -566,7 +566,7 @@ Data BasicContentExecutor::elementAsData(XERCESC_NS::DOMElement* element) { return Data(ATTR(element, "expr"), Data::INTERPRETED); } #endif - return _callbacks->evalAsData(ATTR(element, "expr")); + return _callbacks->evalAsData(ATTR(element, "expr")); } if (HAS_ATTR(element, "src")) { @@ -582,7 +582,7 @@ Data BasicContentExecutor::elementAsData(XERCESC_NS::DOMElement* element) { std::string content = url.getInContent(); // make an attempt to parse as XML - try { + try { XERCESC_NS::XercesDOMParser parser; parser.setValidationScheme(XERCESC_NS::XercesDOMParser::Val_Never); parser.setDoNamespaces(true); @@ -600,8 +600,8 @@ Data BasicContentExecutor::elementAsData(XERCESC_NS::DOMElement* element) { XERCESC_NS::DOMDocument* doc = parser.adoptDocument(); d.adoptedDoc = std::shared_ptr(doc); d.node = doc->getDocumentElement(); - - return d; + + return d; } catch (...) { // just ignore and return as an interpreted string below diff --git a/src/uscxml/interpreter/BasicEventQueue.cpp b/src/uscxml/interpreter/BasicEventQueue.cpp index 3cf4daf..cc5ff04 100644 --- a/src/uscxml/interpreter/BasicEventQueue.cpp +++ b/src/uscxml/interpreter/BasicEventQueue.cpp @@ -36,11 +36,11 @@ Event BasicEventQueue::dequeue(size_t blockMs) { if (blockMs > 0) { - // block for given milliseconds or until queue is filled - auto endTime = std::chrono::system_clock::now() + std::chrono::milliseconds(blockMs); - - while (_queue.empty()) { - _cond.wait_until(_mutex, endTime); + // block for given milliseconds or until queue is filled + auto endTime = std::chrono::system_clock::now() + std::chrono::milliseconds(blockMs); + + while (_queue.empty()) { + _cond.wait_until(_mutex, endTime); } } @@ -61,8 +61,8 @@ void BasicEventQueue::enqueue(const Event& event) { } void BasicEventQueue::reset() { - std::lock_guard lock(_mutex); - _queue.clear(); + std::lock_guard lock(_mutex); + _queue.clear(); } static void dummyCallback(evutil_socket_t fd, short what, void *arg) { @@ -198,9 +198,9 @@ void BasicDelayedEventQueue::stop() { } void BasicDelayedEventQueue::reset() { - std::lock_guard lock(_mutex); - cancelAllDelayed(); - _queue.clear(); + std::lock_guard lock(_mutex); + cancelAllDelayed(); + _queue.clear(); } } \ No newline at end of file diff --git a/src/uscxml/interpreter/BasicEventQueue.h b/src/uscxml/interpreter/BasicEventQueue.h index 1542e30..2bc739e 100644 --- a/src/uscxml/interpreter/BasicEventQueue.h +++ b/src/uscxml/interpreter/BasicEventQueue.h @@ -43,8 +43,8 @@ public: virtual ~BasicEventQueue(); virtual Event dequeue(size_t blockMs); virtual void enqueue(const Event& event); - virtual void reset(); - + virtual void reset(); + protected: std::list _queue; std::recursive_mutex _mutex; @@ -68,7 +68,7 @@ public: virtual void enqueue(const Event& event) { return BasicEventQueue::enqueue(event); } - virtual void reset(); + virtual void reset(); protected: struct callbackData { diff --git a/src/uscxml/interpreter/ContentExecutorImpl.h b/src/uscxml/interpreter/ContentExecutorImpl.h index ad4d695..ca565f0 100644 --- a/src/uscxml/interpreter/ContentExecutorImpl.h +++ b/src/uscxml/interpreter/ContentExecutorImpl.h @@ -66,7 +66,7 @@ public: /** Monitoring */ virtual std::set getMonitors() = 0; - virtual Interpreter getInterpreter() = 0; + virtual Interpreter getInterpreter() = 0; }; diff --git a/src/uscxml/interpreter/EventQueue.cpp b/src/uscxml/interpreter/EventQueue.cpp index 7ff0bfb..dd83f38 100644 --- a/src/uscxml/interpreter/EventQueue.cpp +++ b/src/uscxml/interpreter/EventQueue.cpp @@ -39,7 +39,7 @@ void EventQueue::enqueue(const Event& event) { return _impl->enqueue(event); } void EventQueue::reset() { - return _impl->reset(); + return _impl->reset(); } PIMPL_OPERATORS_INHERIT_IMPL(DelayedEventQueue, EventQueue) diff --git a/src/uscxml/interpreter/EventQueue.h b/src/uscxml/interpreter/EventQueue.h index 37b90be..79d0c26 100644 --- a/src/uscxml/interpreter/EventQueue.h +++ b/src/uscxml/interpreter/EventQueue.h @@ -38,7 +38,7 @@ public: virtual Event dequeue(size_t blockMs); virtual void enqueue(const Event& event); - virtual void reset(); + virtual void reset(); protected: std::shared_ptr _impl; diff --git a/src/uscxml/interpreter/EventQueueImpl.h b/src/uscxml/interpreter/EventQueueImpl.h index befd684..1f99226 100644 --- a/src/uscxml/interpreter/EventQueueImpl.h +++ b/src/uscxml/interpreter/EventQueueImpl.h @@ -42,7 +42,7 @@ class USCXML_API EventQueueImpl { public: virtual Event dequeue(size_t blockMs) = 0; virtual void enqueue(const Event& event) = 0; - virtual void reset() = 0; + virtual void reset() = 0; }; /** diff --git a/src/uscxml/interpreter/FastMicroStep.cpp b/src/uscxml/interpreter/FastMicroStep.cpp index 826df93..b0fda1f 100644 --- a/src/uscxml/interpreter/FastMicroStep.cpp +++ b/src/uscxml/interpreter/FastMicroStep.cpp @@ -91,24 +91,24 @@ FastMicroStep::~FastMicroStep() { void FastMicroStep::resortStates(DOMElement* element, const X& xmlPrefix) { - /** + /** initials deep histories shallow histories everything else */ - DOMElement* child = element->getFirstElementChild(); - while(child) { - resortStates(child, xmlPrefix); - child = child->getNextElementSibling(); - } + DOMElement* child = element->getFirstElementChild(); + while(child) { + resortStates(child, xmlPrefix); + child = child->getNextElementSibling(); + } // shallow history states to top child = element->getFirstElementChild(); while(child) { if (TAGNAME_CAST(child) == xmlPrefix.str() + "history" && - (!HAS_ATTR(element, "type") || iequals(ATTR(element, "type"), "shallow"))) { + (!HAS_ATTR(element, "type") || iequals(ATTR(element, "type"), "shallow"))) { DOMElement* tmp = child->getNextElementSibling(); if (child != element->getFirstChild()) { @@ -154,34 +154,34 @@ void FastMicroStep::resortStates(DOMElement* element, const X& xmlPrefix) { } std::list FastMicroStep::getExitSetCached(const XERCESC_NS::DOMElement* transition, - const XERCESC_NS::DOMElement* root) { - - if (_cache.exitSet.find(transition) == _cache.exitSet.end()) { - _cache.exitSet[transition] = getExitSet(transition, root); - } - - return _cache.exitSet[transition]; + const XERCESC_NS::DOMElement* root) { + + if (_cache.exitSet.find(transition) == _cache.exitSet.end()) { + _cache.exitSet[transition] = getExitSet(transition, root); + } + + return _cache.exitSet[transition]; } bool FastMicroStep::conflictsCached(const DOMElement* t1, const DOMElement* t2, const DOMElement* root) { - if (getSourceState(t1) == getSourceState(t2)) - return true; - - if (DOMUtils::isDescendant(getSourceState(t1), getSourceState(t2))) - return true; - - if (DOMUtils::isDescendant(getSourceState(t2), getSourceState(t1))) - return true; - - if (DOMUtils::hasIntersection(getExitSetCached(t1, root), getExitSetCached(t2, root))) - return true; - - return false; + if (getSourceState(t1) == getSourceState(t2)) + return true; + + if (DOMUtils::isDescendant(getSourceState(t1), getSourceState(t2))) + return true; + + if (DOMUtils::isDescendant(getSourceState(t2), getSourceState(t1))) + return true; + + if (DOMUtils::hasIntersection(getExitSetCached(t1, root), getExitSetCached(t2, root))) + return true; + + return false; } - + void FastMicroStep::init(XERCESC_NS::DOMElement* scxml) { - + _scxml = scxml; _binding = (HAS_ATTR(_scxml, "binding") && iequals(ATTR(_scxml, "binding"), "late") ? LATE : EARLY); _xmlPrefix = _scxml->getPrefix(); @@ -193,7 +193,7 @@ void FastMicroStep::init(XERCESC_NS::DOMElement* scxml) { resortStates(_scxml, _xmlPrefix); // assert(false); // throw NULL; - + /** -- All things states -- */ std::list tmp; @@ -356,8 +356,8 @@ void FastMicroStep::init(XERCESC_NS::DOMElement* scxml) { assert(_transitions[i]->element != NULL); // std::cout << "i: " << i << std::endl << std::flush; std::list exitList = getExitSetCached(_transitions[i]->element, _scxml); - _cache.exitSet[_transitions[i]->element] = exitList; - + _cache.exitSet[_transitions[i]->element] = exitList; + for (j = 0; j < _states.size(); j++) { if (!exitList.empty() && _states[j]->element == exitList.front()) { _transitions[i]->exitSet[j] = true; @@ -369,7 +369,7 @@ void FastMicroStep::init(XERCESC_NS::DOMElement* scxml) { assert(exitList.size() == 0); // establish the transitions' conflict set - for (j = i; j < _transitions.size(); j++) { + for (j = i; j < _transitions.size(); j++) { if (conflictsCached(_transitions[i]->element, _transitions[j]->element, _scxml)) { _transitions[i]->conflicts[j] = true; } else { @@ -377,13 +377,13 @@ void FastMicroStep::init(XERCESC_NS::DOMElement* scxml) { } // std::cout << "."; } - - // conflicts matrix is symmetric - for (j = 0; j < i; j++) { - _transitions[i]->conflicts[j] = _transitions[j]->conflicts[i]; - } - + // conflicts matrix is symmetric + for (j = 0; j < i; j++) { + _transitions[i]->conflicts[j] = _transitions[j]->conflicts[i]; + } + + // establish the transitions' target set std::list targets = tokenize(ATTR(_transitions[i]->element, "target")); for (auto tIter = targets.begin(); tIter != targets.end(); tIter++) { @@ -421,9 +421,9 @@ void FastMicroStep::init(XERCESC_NS::DOMElement* scxml) { // the transitions event and condition _transitions[i]->event = (HAS_ATTR(_transitions[i]->element, "event") ? - ATTR(_transitions[i]->element, "event") : ""); + ATTR(_transitions[i]->element, "event") : ""); _transitions[i]->cond = (HAS_ATTR(_transitions[i]->element, "cond") ? - ATTR(_transitions[i]->element, "cond") : ""); + ATTR(_transitions[i]->element, "cond") : ""); // is there executable content? if (_transitions[i]->element->getChildElementCount() > 0) { @@ -431,7 +431,7 @@ void FastMicroStep::init(XERCESC_NS::DOMElement* scxml) { } } - _cache.exitSet.clear(); + _cache.exitSet.clear(); _isInitialized = true; } @@ -942,11 +942,11 @@ ESTABLISH_ENTRYSET: // are we running in circles? if (_microstepConfigurations.find(_configuration) != _microstepConfigurations.end()) { - InterpreterIssue issue("Reentering same configuration during microstep - possible endless loop", - NULL, - InterpreterIssue::USCXML_ISSUE_WARNING); - - USCXML_MONITOR_CALLBACK1(_callbacks->getMonitors(), + InterpreterIssue issue("Reentering same configuration during microstep - possible endless loop", + NULL, + InterpreterIssue::USCXML_ISSUE_WARNING); + + USCXML_MONITOR_CALLBACK1(_callbacks->getMonitors(), reportIssue, issue); } @@ -1068,7 +1068,7 @@ std::list FastMicroStep::getCompletion(const DOMElement* state) { completion.push_back(initElems.front()); } else { // first child state - for (auto childElem = state->getFirstElementChild(); childElem; childElem = childElem->getNextElementSibling()) { + for (auto childElem = state->getFirstElementChild(); childElem; childElem = childElem->getNextElementSibling()) { if (isState(childElem)) { completion.push_back(childElem); break; diff --git a/src/uscxml/interpreter/FastMicroStep.h b/src/uscxml/interpreter/FastMicroStep.h index dd58480..1fbc8f4 100644 --- a/src/uscxml/interpreter/FastMicroStep.h +++ b/src/uscxml/interpreter/FastMicroStep.h @@ -91,10 +91,10 @@ protected: unsigned char type; }; - class CachedPredicates { - public: - std::map > exitSet; - }; + class CachedPredicates { + public: + std::map > exitSet; + }; virtual void init(XERCESC_NS::DOMElement* scxml); @@ -127,12 +127,12 @@ private: std::list getHistoryCompletion(const XERCESC_NS::DOMElement* state); void resortStates(XERCESC_NS::DOMElement* node, const X& xmlPrefix); - bool conflictsCached(const XERCESC_NS::DOMElement* t1, const XERCESC_NS::DOMElement* t2, const XERCESC_NS::DOMElement* root); ///< overrides implementation Predicates::conflicts for speed + bool conflictsCached(const XERCESC_NS::DOMElement* t1, const XERCESC_NS::DOMElement* t2, const XERCESC_NS::DOMElement* root); ///< overrides implementation Predicates::conflicts for speed - std::list getExitSetCached(const XERCESC_NS::DOMElement* transition, - const XERCESC_NS::DOMElement* root); + std::list getExitSetCached(const XERCESC_NS::DOMElement* transition, + const XERCESC_NS::DOMElement* root); - CachedPredicates _cache; + CachedPredicates _cache; #ifdef USCXML_VERBOSE void printStateNames(const boost::dynamic_bitset<>& bitset); diff --git a/src/uscxml/interpreter/InterpreterImpl.cpp b/src/uscxml/interpreter/InterpreterImpl.cpp index 5cbae3c..d3b044a 100644 --- a/src/uscxml/interpreter/InterpreterImpl.cpp +++ b/src/uscxml/interpreter/InterpreterImpl.cpp @@ -82,27 +82,27 @@ InterpreterImpl::InterpreterImpl() : _isInitialized(false), _document(NULL), _sc InterpreterImpl::~InterpreterImpl() { - - // make sure we deallocate all user-data in the DOM, - // this is neccesary if we were aborted early - std::list invokes = DOMUtils::filterChildElements(_xmlPrefix.str() + "invoke", _scxml, true); - for (auto invoke : invokes) { - char* invokeId = (char*)invoke->getUserData(X("invokeid")); - if (invokeId != NULL) { - free(invokeId); - invoke->setUserData(X("invokeid"), NULL, NULL); - } - } - - if (_delayQueue) - _delayQueue.cancelAllDelayed(); - if (_document) - delete _document; - - { - std::lock_guard lock(_instanceMutex); - _instances.erase(getSessionId()); - } + + // make sure we deallocate all user-data in the DOM, + // this is neccesary if we were aborted early + std::list invokes = DOMUtils::filterChildElements(_xmlPrefix.str() + "invoke", _scxml, true); + for (auto invoke : invokes) { + char* invokeId = (char*)invoke->getUserData(X("invokeid")); + if (invokeId != NULL) { + free(invokeId); + invoke->setUserData(X("invokeid"), NULL, NULL); + } + } + + if (_delayQueue) + _delayQueue.cancelAllDelayed(); + if (_document) + delete _document; + + { + std::lock_guard lock(_instanceMutex); + _instances.erase(getSessionId()); + } // assert(_invokers.size() == 0); // ::xercesc_3_1::XMLPlatformUtils::Terminate(); @@ -377,7 +377,7 @@ void InterpreterImpl::uninvoke(const std::string& invokeId) { if (_invokers.find(invokeId) != _invokers.end()) { _invokers[invokeId].uninvoke(); _autoForwarders.erase(invokeId); - _invokers.erase(invokeId); + _invokers.erase(invokeId); } } diff --git a/src/uscxml/interpreter/InterpreterImpl.h b/src/uscxml/interpreter/InterpreterImpl.h index d6dbd1a..9b784d3 100644 --- a/src/uscxml/interpreter/InterpreterImpl.h +++ b/src/uscxml/interpreter/InterpreterImpl.h @@ -50,9 +50,8 @@ class USCXML_API InterpreterImpl : public MicroStepCallbacks, public DataModelCallbacks, public ContentExecutorCallbacks, - public DelayedEventQueueCallbacks, - public std::enable_shared_from_this -{ + public DelayedEventQueueCallbacks, + public std::enable_shared_from_this { public: enum Binding { EARLY = 0, @@ -77,13 +76,13 @@ public: virtual void reset() {///< Reset state machine if (_microStepper) - _microStepper.reset(); - + _microStepper.reset(); + _isInitialized = false; _state = USCXML_INSTANTIATED; // _dataModel.reset(); - if (_delayQueue) - _delayQueue.reset(); + if (_delayQueue) + _delayQueue.reset(); // _contentExecutor.reset(); } @@ -101,9 +100,9 @@ public: _monitors.insert(monitor); } - void removeMonitor(InterpreterMonitor* monitor) { - _monitors.erase(monitor); - } + void removeMonitor(InterpreterMonitor* monitor) { + _monitors.erase(monitor); + } /** MicrostepCallbacks @@ -136,13 +135,13 @@ public: _execContent.uninvoke(invoke); } - virtual std::set getMonitors() { + virtual std::set getMonitors() { return _monitors; } - virtual Interpreter getInterpreter() { - return Interpreter(shared_from_this()); - } + virtual Interpreter getInterpreter() { + return Interpreter(shared_from_this()); + } /** DataModelCallbacks @@ -230,14 +229,14 @@ public: _execContent = al.execContent; _microStepper = al.microStepper; _dataModel = al.dataModel; - _internalQueue = al.internalQueue; - _externalQueue = al.externalQueue; - _delayQueue = al.delayedQueue; + _internalQueue = al.internalQueue; + _externalQueue = al.externalQueue; + _delayQueue = al.delayedQueue; } - void setFactory(Factory* factory) { - _factory = factory; - } + void setFactory(Factory* factory) { + _factory = factory; + } static std::map > getInstances(); @@ -270,9 +269,9 @@ protected: friend class InterpreterIssue; friend class TransformerImpl; friend class USCXMLInvoker; - friend class SCXMLIOProcessor; - friend class DebugSession; - friend class Debugger; + friend class SCXMLIOProcessor; + friend class DebugSession; + friend class Debugger; X _xmlPrefix; X _xmlNS; @@ -297,7 +296,7 @@ protected: std::map _ioProcs; std::map _invokers; std::set _autoForwarders; - std::set _monitors; + std::set _monitors; private: void setupDOM(); diff --git a/src/uscxml/interpreter/InterpreterMonitor.h b/src/uscxml/interpreter/InterpreterMonitor.h index 10cc6ac..2519cfd 100644 --- a/src/uscxml/interpreter/InterpreterMonitor.h +++ b/src/uscxml/interpreter/InterpreterMonitor.h @@ -47,13 +47,13 @@ for (auto callback : callbacks) { callback->function(inptr, arg1, arg2); } } // forward declare namespace XERCESC_NS { - class DOMElement; +class DOMElement; } namespace uscxml { class Interpreter; - + class USCXML_API InterpreterMonitor { public: InterpreterMonitor() : _copyToInvokers(false) {} diff --git a/src/uscxml/interpreter/MicroStepImpl.h b/src/uscxml/interpreter/MicroStepImpl.h index 40f065c..7d7c9b0 100644 --- a/src/uscxml/interpreter/MicroStepImpl.h +++ b/src/uscxml/interpreter/MicroStepImpl.h @@ -35,7 +35,7 @@ namespace uscxml { class InterpreterMonitor; - + /** * @ingroup microstep * @ingroup callback @@ -61,7 +61,7 @@ public: /** Monitoring */ virtual std::set getMonitors() = 0; - virtual Interpreter getInterpreter() = 0; + virtual Interpreter getInterpreter() = 0; }; /** diff --git a/src/uscxml/plugins/DataModelImpl.h b/src/uscxml/plugins/DataModelImpl.h index a151141..e21be9a 100644 --- a/src/uscxml/plugins/DataModelImpl.h +++ b/src/uscxml/plugins/DataModelImpl.h @@ -43,7 +43,7 @@ class DataModelImpl; */ class USCXML_API DataModelCallbacks { public: - virtual ~DataModelCallbacks() {} ///< silence virtual destructor warning from swig + virtual ~DataModelCallbacks() {} ///< silence virtual destructor warning from swig virtual const std::string& getName() = 0; virtual const std::string& getSessionId() = 0; virtual const std::map& getIOProcessors() = 0; @@ -57,6 +57,7 @@ public: DataModelExtension() : dm(NULL) {} virtual ~DataModelExtension() {} virtual std::string provides() = 0; + virtual Data invoke(const std::string& member, const Data& params) = 0; virtual Data getValueOf(const std::string& member) = 0; virtual void setValueOf(const std::string& member, const Data& data) = 0; DataModelImpl* dm; @@ -117,7 +118,7 @@ public: * @param expr Anything that possibly evaluates to an enumerable object. * @return The number of items in the enumerable object. */ - virtual uint32_t getLength(const std::string& expr) = 0; + virtual uint32_t getLength(const std::string& expr) = 0; /** * Set a given item to the object at a given index for one iteration. diff --git a/src/uscxml/plugins/Factory.cpp b/src/uscxml/plugins/Factory.cpp index 4dabab6..a60fe4c 100644 --- a/src/uscxml/plugins/Factory.cpp +++ b/src/uscxml/plugins/Factory.cpp @@ -56,6 +56,10 @@ # include "uscxml/plugins/datamodel/c89/C89DataModel.h" #endif +#ifdef WITH_DM_PROMELA +# include "uscxml/plugins/datamodel/promela/PromelaDataModel.h" +#endif + #ifdef WITH_INV_SCXML # include "uscxml/plugins/invoker/scxml/USCXMLInvoker.h" @@ -89,66 +93,73 @@ std::string Factory::getDefaultPluginPath() { void Factory::registerPlugins() { #ifdef WITH_IOPROC_SCXML - { - SCXMLIOProcessor* ioProcessor = new SCXMLIOProcessor(); - registerIOProcessor(ioProcessor); - } + { + SCXMLIOProcessor* ioProcessor = new SCXMLIOProcessor(); + registerIOProcessor(ioProcessor); + } #endif #ifdef WITH_IOPROC_BASICHTTP - { - BasicHTTPIOProcessor* ioProcessor = new BasicHTTPIOProcessor(); - registerIOProcessor(ioProcessor); - } + { + BasicHTTPIOProcessor* ioProcessor = new BasicHTTPIOProcessor(); + registerIOProcessor(ioProcessor); + } #endif - + #ifdef WITH_DM_ECMA_V8 - { - V8DataModel* dataModel = new V8DataModel(); - registerDataModel(dataModel); - } + { + V8DataModel* dataModel = new V8DataModel(); + registerDataModel(dataModel); + } #endif #ifdef WITH_DM_ECMA_JSC - { - JSCDataModel* dataModel = new JSCDataModel(); - registerDataModel(dataModel); - } + { + JSCDataModel* dataModel = new JSCDataModel(); + registerDataModel(dataModel); + } #endif - + #ifdef WITH_DM_LUA - { - LuaDataModel* dataModel = new LuaDataModel(); - registerDataModel(dataModel); - } + { + LuaDataModel* dataModel = new LuaDataModel(); + registerDataModel(dataModel); + } #endif #ifdef WITH_DM_C89 - { - C89DataModel* dataModel = new C89DataModel(); - registerDataModel(dataModel); - } + { + C89DataModel* dataModel = new C89DataModel(); + registerDataModel(dataModel); + } #endif - { - NULLDataModel* dataModel = new NULLDataModel(); - registerDataModel(dataModel); - } +#ifdef WITH_DM_PROMELA + { + PromelaDataModel* dataModel = new PromelaDataModel(); + registerDataModel(dataModel); + } +#endif + + { + NULLDataModel* dataModel = new NULLDataModel(); + registerDataModel(dataModel); + } + - #ifdef WITH_INV_SCXML - { - USCXMLInvoker* invoker = new USCXMLInvoker(); - registerInvoker(invoker); - } + { + USCXMLInvoker* invoker = new USCXMLInvoker(); + registerInvoker(invoker); + } #endif - + #ifdef WITH_INV_DIRMON - { - DirMonInvoker* inv = new DirMonInvoker(); - registerInvoker(inv); - } + { + DirMonInvoker* inv = new DirMonInvoker(); + registerInvoker(inv); + } #endif } diff --git a/src/uscxml/plugins/datamodel/CMakeLists.txt b/src/uscxml/plugins/datamodel/CMakeLists.txt index fd08ee0..6409a7a 100644 --- a/src/uscxml/plugins/datamodel/CMakeLists.txt +++ b/src/uscxml/plugins/datamodel/CMakeLists.txt @@ -58,6 +58,17 @@ if (WITH_DM_C89) list (APPEND USCXML_FILES ${C89_DATAMODEL}) endif() +if (WITH_DM_PROMELA) + set(USCXML_DATAMODELS "promela ${USCXML_DATAMODELS}") + # Lua ecmascript datamodel + file(GLOB_RECURSE PROMELA_DATAMODEL + promela/*.cpp + promela/*.c + promela/*.h + ) + list (APPEND USCXML_FILES ${PROMELA_DATAMODEL}) +endif() + if (NOT SWIG_FOUND) message(STATUS "No swig binary found, not generating DOM classes") elseif(SWIG_VERSION VERSION_LESS 3.0.8) diff --git a/src/uscxml/plugins/datamodel/c89/C89DataModel.cpp b/src/uscxml/plugins/datamodel/c89/C89DataModel.cpp index 804b71a..24b9bb1 100644 --- a/src/uscxml/plugins/datamodel/c89/C89DataModel.cpp +++ b/src/uscxml/plugins/datamodel/c89/C89DataModel.cpp @@ -34,13 +34,13 @@ C89DataModel::C89DataModel() { std::shared_ptr C89DataModel::create(DataModelCallbacks* callbacks) { std::shared_ptr dm(new C89DataModel()); - PicocInitialise(&dm->_pc, PICOC_STACK_SIZE); - PicocIncludeAllSystemHeaders(&dm->_pc); - return dm; + PicocInitialise(&dm->_pc, PICOC_STACK_SIZE); + PicocIncludeAllSystemHeaders(&dm->_pc); + return dm; } C89DataModel::~C89DataModel() { - PicocCleanup(&_pc); + PicocCleanup(&_pc); } void C89DataModel::addExtension(DataModelExtension* ext) { @@ -60,7 +60,7 @@ bool C89DataModel::isValidSyntax(const std::string& expr) { } uint32_t C89DataModel::getLength(const std::string& expr) { - return 0; + return 0; } void C89DataModel::setForeach(const std::string& item, diff --git a/src/uscxml/plugins/datamodel/c89/C89DataModel.h b/src/uscxml/plugins/datamodel/c89/C89DataModel.h index 30116e1..4e9eef0 100644 --- a/src/uscxml/plugins/datamodel/c89/C89DataModel.h +++ b/src/uscxml/plugins/datamodel/c89/C89DataModel.h @@ -59,7 +59,7 @@ public: virtual std::list getNames() { std::list names; names.push_back("c89"); - names.push_back("ansi-c"); + names.push_back("ansi-c"); return names; } @@ -86,7 +86,7 @@ public: virtual std::string andExpressions(std::list); protected: - Picoc _pc; + Picoc _pc; }; #ifdef BUILD_AS_PLUGINS diff --git a/src/uscxml/plugins/datamodel/ecmascript/JavaScriptCore/JSCDataModel.cpp b/src/uscxml/plugins/datamodel/ecmascript/JavaScriptCore/JSCDataModel.cpp index 05d37d4..bdb8939 100644 --- a/src/uscxml/plugins/datamodel/ecmascript/JavaScriptCore/JSCDataModel.cpp +++ b/src/uscxml/plugins/datamodel/ecmascript/JavaScriptCore/JSCDataModel.cpp @@ -401,23 +401,23 @@ Data JSCDataModel::evalAsData(const std::string& content) { Data JSCDataModel::getAsData(const std::string& content) { // parse as JSON test 578 - Data d = Data::fromJSON(content); - if (!d.empty()) - return d; - - std::string trimmed = boost::trim_copy(content); - if (trimmed.length() > 0) { - if (isNumeric(trimmed.c_str(), 10)) { - d = Data(trimmed, Data::INTERPRETED); - } else if (trimmed.length() >= 2 && - ((trimmed[0] == '"' && trimmed[trimmed.length() - 1] == '"') || - (trimmed[0] == '\'' && trimmed[trimmed.length() - 1] == '\''))) { - d = Data(trimmed.substr(1, trimmed.length() - 2), Data::VERBATIM); - } else { - d = Data(trimmed, Data::INTERPRETED); - } - } - return d; + Data d = Data::fromJSON(content); + if (!d.empty()) + return d; + + std::string trimmed = boost::trim_copy(content); + if (trimmed.length() > 0) { + if (isNumeric(trimmed.c_str(), 10)) { + d = Data(trimmed, Data::INTERPRETED); + } else if (trimmed.length() >= 2 && + ((trimmed[0] == '"' && trimmed[trimmed.length() - 1] == '"') || + (trimmed[0] == '\'' && trimmed[trimmed.length() - 1] == '\''))) { + d = Data(trimmed.substr(1, trimmed.length() - 2), Data::VERBATIM); + } else { + d = Data(trimmed, Data::INTERPRETED); + } + } + return d; } JSValueRef JSCDataModel::getDataAsValue(const Data& data) { diff --git a/src/uscxml/plugins/datamodel/ecmascript/v8/V8DataModel.cpp b/src/uscxml/plugins/datamodel/ecmascript/v8/V8DataModel.cpp index db65ebf..0205674 100644 --- a/src/uscxml/plugins/datamodel/ecmascript/v8/V8DataModel.cpp +++ b/src/uscxml/plugins/datamodel/ecmascript/v8/V8DataModel.cpp @@ -423,23 +423,23 @@ void V8DataModel::setEvent(const Event& event) { } Data V8DataModel::getAsData(const std::string& content) { - Data d = Data::fromJSON(content); - if (!d.empty()) - return d; - - std::string trimmed = boost::trim_copy(content); - if (trimmed.length() > 0) { - if (isNumeric(trimmed.c_str(), 10)) { - d = Data(trimmed, Data::INTERPRETED); - } else if (trimmed.length() >= 2 && - ((trimmed[0] == '"' && trimmed[trimmed.length() - 1] == '"') || - (trimmed[0] == '\'' && trimmed[trimmed.length() - 1] == '\''))) { - d = Data(trimmed.substr(1, trimmed.length() - 2), Data::VERBATIM); - } else { - d = Data(trimmed, Data::INTERPRETED); - } - } - return d; + Data d = Data::fromJSON(content); + if (!d.empty()) + return d; + + std::string trimmed = boost::trim_copy(content); + if (trimmed.length() > 0) { + if (isNumeric(trimmed.c_str(), 10)) { + d = Data(trimmed, Data::INTERPRETED); + } else if (trimmed.length() >= 2 && + ((trimmed[0] == '"' && trimmed[trimmed.length() - 1] == '"') || + (trimmed[0] == '\'' && trimmed[trimmed.length() - 1] == '\''))) { + d = Data(trimmed.substr(1, trimmed.length() - 2), Data::VERBATIM); + } else { + d = Data(trimmed, Data::INTERPRETED); + } + } + return d; } Data V8DataModel::evalAsData(const std::string& content) { diff --git a/src/uscxml/plugins/datamodel/lua/LuaDataModel.cpp b/src/uscxml/plugins/datamodel/lua/LuaDataModel.cpp index ca8cc60..4b7ed67 100644 --- a/src/uscxml/plugins/datamodel/lua/LuaDataModel.cpp +++ b/src/uscxml/plugins/datamodel/lua/LuaDataModel.cpp @@ -79,12 +79,12 @@ static Data getLuaAsData(lua_State* _luaState, const luabridge::LuaRef& lua) { bool isArray = false; bool isMap = false; for (luabridge::Iterator iter (lua); !iter.isNil(); ++iter) { - luabridge::LuaRef luaKey = iter.key(); + luabridge::LuaRef luaKey = iter.key(); luabridge::LuaRef luaVal = *iter; if (luaKey.isString()) { - assert(!isArray); + assert(!isArray); isMap = true; - // luaKey.tostring() is not working?! see issue84 + // luaKey.tostring() is not working?! see issue84 data.compound[luaKey.cast()] = getLuaAsData(_luaState, luaVal); } else { assert(!isMap); @@ -335,23 +335,23 @@ Data LuaDataModel::evalAsData(const std::string& content) { data = getLuaAsData(_luaState, luabridge::LuaRef::fromStack(_luaState, -1)); } lua_pop(_luaState, retVals); - return data; + return data; } catch (ErrorEvent e) { - } - - try { + } + + try { // evaluate again without the return() - int retVals = luaEval(_luaState, trimmedExpr); - + int retVals = luaEval(_luaState, trimmedExpr); + if (retVals == 1) { data = getLuaAsData(_luaState, luabridge::LuaRef::fromStack(_luaState, -1)); - } - lua_pop(_luaState, retVals); - return data; + } + lua_pop(_luaState, retVals); + return data; - } catch (ErrorEvent e) { - throw e; // we will assume syntax error and throw - } + } catch (ErrorEvent e) { + throw e; // we will assume syntax error and throw + } return data; } @@ -470,59 +470,59 @@ void LuaDataModel::assign(const std::string& location, const Data& data) { int retVals = luaEval(_luaState, location + " = " + location); lua_pop(_luaState, retVals); - std::list > idPath; - size_t start = 0; - for (size_t i = 0; i < location.size(); i++) { - if (location[i] == '.' || location[i] == '[') { - idPath.push_back(std::make_pair(location.substr(start, i - start), false)); - start = i + 1; - } else if (location[i] == ']') { - idPath.push_back(std::make_pair(location.substr(start, i - start), true)); - start = i + 1; - } - } - if (start < location.size()) - idPath.push_back(std::make_pair(location.substr(start, location.size() - start), false)); - - if (idPath.size() == 0) - return; - - luabridge::LuaRef lua = getDataAsLua(_luaState, data); - - if (idPath.size() == 1) { - // trivial case where we reference a simple toplevel identifier - luabridge::setGlobal(_luaState, lua, location.c_str()); - - } else { - auto globalId = idPath.front(); - idPath.pop_front(); - - auto field = idPath.back(); - idPath.pop_back(); - - luabridge::LuaRef topValue = luabridge::getGlobal(_luaState, globalId.first.c_str()); - luabridge::LuaRef value = topValue; - - for (auto ident : idPath) { - if (!value.isTable()) - value = luabridge::newTable(_luaState); - - if (ident.second) { - luabridge::LuaRef tmp = value[strTo(ident.first)]; - } else { - luabridge::LuaRef tmp = value[ident]; - value = tmp; - } - } - if (field.second) { - value[strTo(field.first)] = lua; - } else { - value[field.first] = lua; - } - - } - - + std::list > idPath; + size_t start = 0; + for (size_t i = 0; i < location.size(); i++) { + if (location[i] == '.' || location[i] == '[') { + idPath.push_back(std::make_pair(location.substr(start, i - start), false)); + start = i + 1; + } else if (location[i] == ']') { + idPath.push_back(std::make_pair(location.substr(start, i - start), true)); + start = i + 1; + } + } + if (start < location.size()) + idPath.push_back(std::make_pair(location.substr(start, location.size() - start), false)); + + if (idPath.size() == 0) + return; + + luabridge::LuaRef lua = getDataAsLua(_luaState, data); + + if (idPath.size() == 1) { + // trivial case where we reference a simple toplevel identifier + luabridge::setGlobal(_luaState, lua, location.c_str()); + + } else { + auto globalId = idPath.front(); + idPath.pop_front(); + + auto field = idPath.back(); + idPath.pop_back(); + + luabridge::LuaRef topValue = luabridge::getGlobal(_luaState, globalId.first.c_str()); + luabridge::LuaRef value = topValue; + + for (auto ident : idPath) { + if (!value.isTable()) + value = luabridge::newTable(_luaState); + + if (ident.second) { + luabridge::LuaRef tmp = value[strTo(ident.first)]; + } else { + luabridge::LuaRef tmp = value[ident]; + value = tmp; + } + } + if (field.second) { + value[strTo(field.first)] = lua; + } else { + value[field.first] = lua; + } + + } + + // std::cout << Data::toJSON(evalAsData(location)) << std::endl; } } diff --git a/src/uscxml/plugins/datamodel/promela/PromelaDataModel.cpp b/src/uscxml/plugins/datamodel/promela/PromelaDataModel.cpp new file mode 100644 index 0000000..458e372 --- /dev/null +++ b/src/uscxml/plugins/datamodel/promela/PromelaDataModel.cpp @@ -0,0 +1,728 @@ +/** + * @file + * @author 2012-2014 Stefan Radomski (stefan.radomski@cs.tu-darmstadt.de) + * @copyright Simplified BSD + * + * @cond + * This program is free software: you can redistribute it and/or modify + * it under the terms of the FreeBSD license as published by the FreeBSD + * project. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * You should have received a copy of the FreeBSD license along with this + * program. If not, see . + * @endcond + */ + +#include + +#include "uscxml/Common.h" +#include "uscxml/config.h" +#include "uscxml/util/String.h" +#include "PromelaDataModel.h" +#include "uscxml/util/DOM.h" + +#include + +#include "PromelaParser.h" +#include "parser/promela.tab.hpp" +#include + +#ifdef BUILD_AS_PLUGINS +#include +#endif + +#define INVALID_ASSIGNMENT(name) \ +name.compare("_sessionid") == 0 || \ +name.compare("_name") == 0 || \ +name.compare("_ioprocessors") == 0 || \ +name.compare("_event") == 0 + +namespace uscxml { + +#ifdef BUILD_AS_PLUGINS +PLUMA_CONNECTOR +bool pluginConnect(pluma::Host& host) { + host.add( new PromelaDataModelProvider() ); + return true; +} +#endif + +PromelaDataModel::PromelaDataModel() { +} + +PromelaDataModel::~PromelaDataModel() { +} + +std::shared_ptr PromelaDataModel::create(DataModelCallbacks* callbacks) { + std::shared_ptr dm(new PromelaDataModel()); + + dm->_callbacks = callbacks; + + // session id + Data sessionId; + sessionId.compound["type"] = Data("string", Data::VERBATIM); + sessionId.compound["value"] = Data(callbacks->getSessionId(), Data::VERBATIM); + dm->_variables["_sessionid"] = sessionId; + + // name + Data name; + name.compound["type"] = Data("string", Data::VERBATIM); + name.compound["value"] = Data(callbacks->getName(), Data::VERBATIM); + dm->_variables["_name"] = name; + + // ioprocessors + Data ioProcs; + ioProcs.compound["type"] = Data("compound", Data::VERBATIM); + + std::map ioProcessors = callbacks->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; +} + + +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 (false) { +#if 0 + else 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(spaceNormalize(event.content), Data::VERBATIM); + } + } +#endif + } 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::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; + } + + } + + bool PromelaDataModel::isValidSyntax(const std::string& expr) { + try { + PromelaParser parser(expr); + } catch (Event e) { + LOG(ERROR) << e << std::endl; + return false; + } + return true; + } + + uint32_t PromelaDataModel::getLength(const std::string& expr) { + if (!isDeclared(expr)) { + ERROR_EXECUTION_THROW("Variable '" + expr + "' was not declared"); + } + + if (!_variables[expr].hasKey("size")) { + ERROR_EXECUTION_THROW("Variable '" + expr + "' is no array"); + } + + return strTo(_variables[expr]["size"].atom); + } + + void PromelaDataModel::setForeach(const std::string& item, + const std::string& array, + const std::string& index, + uint32_t iteration) { + // assign array element to item + std::stringstream ss; + ss << array << "[" << iteration << "]"; + + 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, 1, PromelaParser::PROMELA_EXPR); + setVariable(indexParser.ast, iteration); + } + + } + + bool PromelaDataModel::evalAsBool(const std::string& expr) { + PromelaParser parser(expr, 1, PromelaParser::PROMELA_EXPR); +// parser.dump(); + Data tmp = evaluateExpr(parser.ast); + + if (tmp.atom.compare("false") == 0) + return false; + if (tmp.atom.compare("0") == 0) + return false; + return true; + } + + Data PromelaDataModel::evalAsData(const std::string& expr) { + PromelaParser parser(expr); + return evaluateExpr(parser.ast); + } + + Data PromelaDataModel::getAsData(const std::string& content) { + return evalAsData(content); + } + + 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; +// node->dump(); + if (false) { + } else if (node->type == PML_DECL) { + std::list::iterator opIter = node->operands.begin(); + PromelaParserNode* vis = *opIter++; + PromelaParserNode* type = *opIter++; + PromelaParserNode* varlist = *opIter++; + + for (std::list::iterator nameIter = varlist->operands.begin(); + nameIter != varlist->operands.end(); + nameIter++) { + Data variable; + variable.compound["vis"] = Data(vis->value, Data::VERBATIM); + variable.compound["type"] = Data(type->value, Data::VERBATIM); + + if (false) { + } else if ((*nameIter)->type == PML_NAME) { + // plain variables without initial assignment + + if (type->value == "mtype") { + variable.compound["value"] = Data(_lastMType++, Data::INTERPRETED); + } else { + variable.compound["value"] = Data(0, Data::INTERPRETED); + } + _variables.compound[(*nameIter)->value] = variable; + + } else if ((*nameIter)->type == PML_ASGN) { + // initially assigned variables + + std::list::iterator opIterAsgn = (*nameIter)->operands.begin(); + PromelaParserNode* name = *opIterAsgn++; + PromelaParserNode* expr = *opIterAsgn++; + + try { + variable.compound["value"] = evaluateExpr(expr); + } catch(uscxml::Event e) { + // test277, declare and throw + _variables.compound[name->value] = variable; + throw e; + } + + assert(opIterAsgn == (*nameIter)->operands.end()); + _variables.compound[name->value] = variable; + } else if ((*nameIter)->type == PML_VAR_ARRAY) { + // variable arrays + + std::list::iterator opIterAsgn = (*nameIter)->operands.begin(); + PromelaParserNode* name = *opIterAsgn++; + int size = dataToInt(evaluateExpr(*opIterAsgn++)); + + variable.compound["size"] = size; + for (size_t i = 0; i < size; i++) { + variable.compound["value"].array.push_back(Data(0, Data::INTERPRETED)); + } + + assert(opIterAsgn == (*nameIter)->operands.end()); + _variables.compound[name->value] = variable; + + } else { + ERROR_EXECUTION_THROW("Declaring variables via " + PromelaParserNode::typeToDesc((*nameIter)->type) + " not implemented"); + } + } + assert(opIter == node->operands.end()); + } else if (node->type == PML_DECLLIST) { + for (std::list::iterator declIter = node->operands.begin(); + declIter != node->operands.end(); + declIter++) { + evaluateDecl(*declIter); + } + } else { + node->dump(); + ERROR_EXECUTION_THROW("Declaring variables via " + PromelaParserNode::typeToDesc(node->type) + " not implemented"); + } + } + + 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); +// return Data(node->value, Data::INTERPRETED); + } + case PML_PLUS: + return dataToInt(evaluateExpr(*opIter++)) + dataToInt(evaluateExpr(*opIter++)); + case PML_MINUS: + return dataToInt(evaluateExpr(*opIter++)) - dataToInt(evaluateExpr(*opIter++)); + case PML_DIVIDE: + return dataToInt(evaluateExpr(*opIter++)) / dataToInt(evaluateExpr(*opIter++)); + case PML_MODULO: + 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 dataToInt(evaluateExpr(*opIter++)) < dataToInt(evaluateExpr(*opIter++)); + case PML_LE: + return dataToInt(evaluateExpr(*opIter++)) <= dataToInt(evaluateExpr(*opIter++)); + case PML_GT: + return dataToInt(evaluateExpr(*opIter++)) > dataToInt(evaluateExpr(*opIter++)); + case PML_GE: + return dataToInt(evaluateExpr(*opIter++)) >= dataToInt(evaluateExpr(*opIter++)); + case PML_TIMES: + return dataToInt(evaluateExpr(*opIter++)) * dataToInt(evaluateExpr(*opIter++)); + case PML_LSHIFT: + return dataToInt(evaluateExpr(*opIter++)) << dataToInt(evaluateExpr(*opIter++)); + case PML_RSHIFT: + return dataToInt(evaluateExpr(*opIter++)) >> dataToInt(evaluateExpr(*opIter++)); + case PML_AND: + 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"); + } + return 0; + } + + void PromelaDataModel::evaluateStmnt(void* ast) { + PromelaParserNode* node = (PromelaParserNode*)ast; + std::list::iterator opIter = node->operands.begin(); + switch (node->type) { + case PML_ASGN: { + PromelaParserNode* name = *opIter++; + PromelaParserNode* expr = *opIter++; + setVariable(name, evaluateExpr(expr)); + break; + } + case PML_STMNT: { + while(opIter != node->operands.end()) { + evaluateStmnt(*opIter++); + } + break; + } + case PML_INCR: { + PromelaParserNode* name = *opIter++; + setVariable(name, strTo(getVariable(name)) + 1); + break; + } + case PML_DECR: { + PromelaParserNode* name = *opIter++; + setVariable(name, strTo(getVariable(name)) - 1); + break; + } + default: + node->dump(); + ERROR_EXECUTION_THROW("No support for " + PromelaParserNode::typeToDesc(node->type) + " statement implemented"); + } + } + + + void PromelaDataModel::setVariable(void* ast, const Data& value) { + PromelaParserNode* node = (PromelaParserNode*)ast; + + if (INVALID_ASSIGNMENT(node->value)) { + ERROR_EXECUTION_THROW("Cannot assign to " + node->value); + } + +// if (_variables.compound.find(name->value) == _variables.compound.end()) { +// // declare implicitly / convenience +// evaluateDecl(ast); +// } + + switch (node->type) { + case PML_VAR_ARRAY: { + std::list::iterator opIter = node->operands.begin(); + + PromelaParserNode* name = *opIter++; + PromelaParserNode* expr = *opIter++; + + // is the location an array? + if (!_variables[name->value].hasKey("size")) { + ERROR_EXECUTION_THROW("Variable " + name->value + " is no array"); + } + + // is the array large enough? + int index = dataToInt(evaluateExpr(expr)); + 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"); + } + + _variables.compound[name->value].compound["value"][index] = value; + + break; + } + case PML_NAME: { + // location is an array, but no array was passed + if (_variables[node->value].hasKey("size")) { + if (value.compound.size() > 0 || value.atom.size() > 0) + ERROR_EXECUTION_THROW("Variable " + node->value + " is an array"); + + if (strTo(_variables[node->value].compound["size"].atom) < value.array.size()) + ERROR_EXECUTION_THROW("Array assigned to " + node->value + " is too large"); + } + + _variables.compound[node->value].compound["value"] = value; + break; + } + case PML_CMPND: { + std::list::iterator opIter = node->operands.begin(); + PromelaParserNode* name = *opIter++; + + // location is no array + if (_variables[name->value].hasKey("size")) { + ERROR_EXECUTION_THROW("Variable " + name->value + " is an array"); + } + +// std::cout << Data::toJSON(_variables) << std::endl;; + + Data* var = &_variables[name->value].compound["value"]; + var->compound["type"] = Data("compound", Data::VERBATIM); + var->compound["vis"] = Data("", Data::VERBATIM); + + while(opIter != node->operands.end()) { + name = *opIter; + opIter++; + var = &(var->compound[name->value]); + } + *var = value; + + break; + } + default: + node->dump(); + ERROR_EXECUTION_THROW("No support for " + PromelaParserNode::typeToDesc(node->type) + " variables implemented"); + break; + } + +// std::cout << Data::toJSON(_variables) << std::endl; + } + + Data PromelaDataModel::getVariable(void* ast) { + PromelaParserNode* node = (PromelaParserNode*)ast; +// node->dump(); + + std::list::iterator opIter = node->operands.begin(); + switch(node->type) { + case PML_NAME: + 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 _variables[node->value]["value"]; + case PML_VAR_ARRAY: { + PromelaParserNode* name = *opIter++; + PromelaParserNode* expr = *opIter++; + int index = dataToInt(evaluateExpr(expr)); + + if (_variables.compound.find(name->value) == _variables.compound.end()) { + ERROR_EXECUTION_THROW("No variable " + name->value + " was declared"); + } + + if (!_variables[name->value].hasKey("size")) { + ERROR_EXECUTION_THROW("Variable " + name->value + " is no array"); + } + + 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 _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(_callbacks->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"); + } + return 0; + } + + std::string PromelaDataModel::andExpressions(std::list expressions) { + + if (expressions.size() == 0) + return ""; + + if (expressions.size() == 1) + return *(expressions.begin()); + + std::ostringstream exprSS; + exprSS << "("; + std::string conjunction = ""; + for (std::list::const_iterator exprIter = expressions.begin(); + exprIter != expressions.end(); + exprIter++) { + exprSS << conjunction << "(" << *exprIter << ")"; + conjunction = " && "; + } + exprSS << ")"; + return exprSS.str(); + } + + void PromelaDataModel::assign(const std::string& location, const Data& data) { + // used for e.g. to assign command line parameters and idlocation + PromelaParser parser(location); + setVariable(parser.ast, data); + } + + void PromelaDataModel::init(const std::string& location, const Data& data) { + assign(location, data); + } + + bool PromelaDataModel::isDeclared(const std::string& expr) { + PromelaParser parser(expr); +// parser.dump(); + if (parser.ast->type == PML_VAR_ARRAY) + return _variables.compound.find(parser.ast->operands.front()->value) != _variables.compound.end(); + + if (parser.ast->type == PML_CMPND) { + // JSON declaration + std::list::iterator opIter = parser.ast->operands.begin(); + Data* var = &_variables; + + while(opIter != parser.ast->operands.end()) { + std::string name = (*opIter)->value; + opIter++; + if (var->compound.find(name) != var->compound.end()) { + var = &(var->compound.at(name)); + } else if (var->compound.find("value") != var->compound.end() && var->compound.at("value").compound.find(name) != var->compound.at("value").compound.end()) { + var = &(var->compound.at("value").compound.at(name)); + } else { + return false; + } + } + return true; + + } + + return _variables.compound.find(expr) != _variables.compound.end(); + } + + void PromelaDataModel::addExtension(DataModelExtension* ext) { + ERROR_EXECUTION_THROW("Extensions unimplemented in promela datamodel"); + } + + +} diff --git a/src/uscxml/plugins/datamodel/promela/PromelaDataModel.h b/src/uscxml/plugins/datamodel/promela/PromelaDataModel.h new file mode 100644 index 0000000..2c1f58d --- /dev/null +++ b/src/uscxml/plugins/datamodel/promela/PromelaDataModel.h @@ -0,0 +1,102 @@ +/** + * @file + * @author 2012-2014 Stefan Radomski (stefan.radomski@cs.tu-darmstadt.de) + * @copyright Simplified BSD + * + * @cond + * This program is free software: you can redistribute it and/or modify + * it under the terms of the FreeBSD license as published by the FreeBSD + * project. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * You should have received a copy of the FreeBSD license along with this + * program. If not, see . + * @endcond + */ + +#ifndef PROMELADATAMODEL_H_4VG0TDMU +#define PROMELADATAMODEL_H_4VG0TDMU + +#include "uscxml/plugins/DataModelImpl.h" +#include + +#ifdef BUILD_AS_PLUGINS +#include "uscxml/plugins/Plugins.h" +#endif + +namespace uscxml { + +class PromelaDataModel : public DataModelImpl { +public: + PromelaDataModel(); + virtual ~PromelaDataModel(); + virtual std::shared_ptr create(DataModelCallbacks* callbacks); + + virtual std::list getNames() { + std::list names; + names.push_back("promela"); + return names; + } + + virtual void addExtension(DataModelExtension* ext); + + virtual bool isValidSyntax(const std::string& expr); + + virtual void setEvent(const Event& event); + + // foreach + virtual uint32_t getLength(const std::string& expr); + virtual void setForeach(const std::string& item, + const std::string& array, + const std::string& index, + uint32_t iteration); + + virtual bool evalAsBool(const std::string& expr); + virtual Data evalAsData(const std::string& expr); + virtual Data getAsData(const std::string& content); + + virtual bool isDeclared(const std::string& expr); + + virtual void assign(const std::string& location, const Data& data); + virtual void init(const std::string& location, const Data& data); + + virtual std::string andExpressions(std::list); + +protected: + + int dataToInt(const Data& data); + bool dataToBool(const Data& data); + + void evaluateDecl(void* ast); + Data evaluateExpr(void* ast); + void evaluateStmnt(void* ast); + + void evaluateDecl(const std::string& expr); + Data evaluateExpr(const std::string& expr); + void evaluateStmnt(const std::string& expr); + + void setVariable(void* ast, const Data& value); + Data getVariable(void* ast); + + void adaptType(Data& data); + + int _lastMType; + + Event _event; + std::string _name; + std::string _sessionId; + + Data _variables; + +}; + +#ifdef BUILD_AS_PLUGINS +PLUMA_INHERIT_PROVIDER(PromelaDataModel, DataModelImpl); +#endif + +} + +#endif /* end of include guard: PROMELADATAMODEL_H_4VG0TDMU */ diff --git a/src/uscxml/plugins/datamodel/promela/PromelaParser.cpp b/src/uscxml/plugins/datamodel/promela/PromelaParser.cpp new file mode 100644 index 0000000..3467598 --- /dev/null +++ b/src/uscxml/plugins/datamodel/promela/PromelaParser.cpp @@ -0,0 +1,298 @@ +/** + * @file + * @author 2012-2014 Stefan Radomski (stefan.radomski@cs.tu-darmstadt.de) + * @copyright Simplified BSD + * + * @cond + * This program is free software: you can redistribute it and/or modify + * it under the terms of the FreeBSD license as published by the FreeBSD + * project. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * You should have received a copy of the FreeBSD license along with this + * program. If not, see . + * @endcond + */ + +#include "PromelaParser.h" +#include "parser/promela.tab.hpp" +#include "uscxml/messages/Event.h" + +#include + +struct yy_buffer_state; +typedef yy_buffer_state *YY_BUFFER_STATE; +extern YY_BUFFER_STATE promela__scan_buffer(char *, size_t, void*); +void promela__delete_buffer(YY_BUFFER_STATE, void*); +YY_BUFFER_STATE promela__scan_string (const char * yystr , void*); + + +extern int promela_lex (PROMELA_STYPE* yylval_param, PROMELA_LTYPE* yylloc_param, void* yyscanner); +int promela_lex_init (void**); +int promela_lex_destroy (void*); + +void promela_error (void* yylloc_param, uscxml::PromelaParser* ctx, void* yyscanner, const char* err) { + PROMELA_LTYPE* yylloc = (PROMELA_LTYPE*)yylloc_param; + // mark as pending exception as we cannot throw from constructor and have the destructor called + ERROR_EXECUTION(excEvent, err); + excEvent.data.compound["line"] = uscxml::Data(yylloc->first_line, uscxml::Data::VERBATIM); + excEvent.data.compound["col"] = uscxml::Data(yylloc->first_column, uscxml::Data::VERBATIM); + + std::stringstream ssUnderline; + for (size_t i = 0; i < yylloc->first_column; i++) + ssUnderline << " "; + ssUnderline << "^"; + excEvent.data.compound["sourcemark"] = uscxml::Data(ssUnderline.str(), uscxml::Data::VERBATIM); + + ctx->pendingException = excEvent; +} + +namespace uscxml { + +PromelaParser::PromelaParser(const std::string& expr) { + init(expr); +} + +PromelaParser::PromelaParser(const std::string& expr, int nrArgs, ...) { + init(expr); + + 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()); + + promela_lex_init(&scanner); + // promela_assign_set_extra(ast, &scanner); + buffer = promela__scan_string(input, scanner); + // buffer = promela__scan_buffer(input, input_length, scanner); + promela_parse(this, scanner); + if (pendingException.name.size() > 0) { + // parsing failed in promela_error + destroy(); + pendingException.data.compound["sourceline"] = Data(expr, Data::VERBATIM); + throw pendingException; + } +} + +void PromelaParser::destroy() { + if (ast) + delete(ast); + free(input); + promela__delete_buffer((YY_BUFFER_STATE)buffer, scanner); + promela_lex_destroy(scanner); +} + +PromelaParser::~PromelaParser() { + destroy(); +} + +std::string PromelaParser::typeToDesc(int type) { + switch (type) { + case PROMELA_EXPR: + return "expression"; + case PROMELA_DECL: + return "declarations"; + case PROMELA_STMNT: + return "statements"; + default: + break; + } + return ""; +} + +PromelaParserNode::~PromelaParserNode() { + while(operands.size() > 0) { + delete operands.front(); + operands.pop_front(); + } + if (loc) + free(loc); +} + +PromelaParserNode* PromelaParser::node(int type, int nrArgs, ...) { + PromelaParserNode* newNode = new PromelaParserNode(); + + newNode->type = type; + va_list ap; + va_start(ap, nrArgs); + for(int i = 1; i <= nrArgs; i++) { + newNode->operands.push_back(va_arg(ap, PromelaParserNode*)); + newNode->operands.back()->parent = newNode; + } + return newNode; +} + +PromelaParserNode* PromelaParser::value(int type, void* location, const char* value) { + PromelaParserNode* newNode = new PromelaParserNode(); + + if (location) { + PROMELA_LTYPE* location_param = (PROMELA_LTYPE*)location; + newNode->loc = (PromelaParserNode::Location*)malloc(sizeof(PromelaParserNode::Location)); + newNode->loc->firstCol = location_param->first_column; + newNode->loc->firstLine = location_param->first_line; + newNode->loc->lastCol = location_param->last_column; + newNode->loc->lastLine = location_param->last_line; + } + + newNode->value = value; + newNode->type = type; + return newNode; +} + + +void PromelaParser::dump() { + switch (type) { + case PROMELA_EXPR: + std::cout << "Promela Expression" << std::endl; + break; + case PROMELA_DECL: + std::cout << "Promela Declarations" << std::endl; + break; + case PROMELA_STMNT: + std::cout << "Promela Statement" << std::endl; + break; + } + ast->dump(); +} + + +void PromelaParserNode::merge(PromelaParserNode* node) { + for (std::list::iterator iter = node->operands.begin(); + iter != node->operands.end(); iter++) { + operands.push_back(*iter); + (*iter)->parent = this; + } + node->operands.clear(); +} + +void PromelaParserNode::push(PromelaParserNode* node) { + node->parent = this; + operands.push_back(node); +} + +void PromelaParserNode::dump(int indent) { + std::string padding; + for (size_t i = 0; i < indent; i++) { + padding += " "; + } + std::cout << padding << typeToDesc(type) << ": " << value; + if (loc != NULL) { + std::cout << " (" << loc->firstLine << ":" << loc->firstCol << ")-(" << loc->lastLine << ":" << loc->lastCol << ")"; + } + std::cout << std::endl; + for (std::list::iterator iter = operands.begin(); + iter != operands.end(); iter++) { + (*iter)->dump(indent + 1); + } +} + +std::string PromelaParserNode::typeToDesc(int type) { + switch(type) { + case PML_PLUS: + return "PLUS"; + case PML_MINUS: + return "MINUS"; + case PML_TIMES: + return "TIMES"; + case PML_DIVIDE: + return "DIVIDE"; + case PML_MODULO: + return "MODULO"; + case PML_BITAND: + return "BITAND"; + case PML_BITXOR: + return "BITXOR"; + case PML_BITOR: + return "BITOR"; + case PML_GT: + return "GT"; + case PML_LT: + return "LT"; + case PML_GE: + return "GE"; + case PML_LE: + return "LE"; + case PML_EQ: + return "EQ"; + case PML_NE: + return "NE"; + case PML_AND: + return "AND"; + case PML_OR: + return "OR"; + case PML_LSHIFT: + return "LSHIFT"; + case PML_RSHIFT: + return "RSHIFT"; + case PML_NEG: + return "NEG"; + case PML_ASGN: + return "ASGN"; + case PML_INCR: + return "INCR"; + case PML_DECR: + return "DECR"; + case PML_VAR_ARRAY: + return "VAR_ARRAY"; + case PML_DECL: + return "DECL"; + case PML_STMNT: + return "STMNT"; + case PML_TYPE: + return "TYPE"; + case PML_NAME: + return "NAME"; + case PML_CONST: + return "CONST"; + case PML_PRINT: + return "PRINT"; + case PML_SHOW: + return "SHOW"; + case PML_EXPR: + return "EXPR"; + case PML_VARLIST: + return "VARLIST"; + case PML_DECLLIST: + 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) + ")"; + } +} + +} \ No newline at end of file diff --git a/src/uscxml/plugins/datamodel/promela/PromelaParser.h b/src/uscxml/plugins/datamodel/promela/PromelaParser.h new file mode 100644 index 0000000..51a2111 --- /dev/null +++ b/src/uscxml/plugins/datamodel/promela/PromelaParser.h @@ -0,0 +1,106 @@ +/** + * @file + * @author 2012-2014 Stefan Radomski (stefan.radomski@cs.tu-darmstadt.de) + * @copyright Simplified BSD + * + * @cond + * This program is free software: you can redistribute it and/or modify + * it under the terms of the FreeBSD license as published by the FreeBSD + * project. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * You should have received a copy of the FreeBSD license along with this + * program. If not, see . + * @endcond + */ + +// bison -v promela.ypp && flex promela.l + +#ifndef PROMELA_H_9AB78YB1 +#define PROMELA_H_9AB78YB1 + +#include +//#include +#include +#include +#include + +#include "uscxml/messages/Event.h" + +namespace uscxml { + +class PromelaParser; + +class PromelaParserNode { +public: + struct Location { + int firstLine; + int firstCol; + int lastLine; + int lastCol; + }; + + PromelaParserNode() : type(0), parent(NULL), loc(NULL) {} + virtual ~PromelaParserNode(); + + void merge(PromelaParserNode* node); + void push(PromelaParserNode* node); + void dump(int indent = 0); + + static std::string typeToDesc(int type); + + int type; + std::string value; + std::list operands; + PromelaParserNode* parent; + Location* loc; +}; + +class PromelaParser { +public: + enum Type { + PROMELA_EXPR, + PROMELA_DECL, + PROMELA_STMNT + }; + + static std::string typeToDesc(int type); + + PromelaParser() : ast(NULL) {} + PromelaParser(const std::string& expr); + PromelaParser(const std::string& expr, int nrArgs, ...); + virtual ~PromelaParser(); + + virtual PromelaParserNode* node(int type, int nrArgs, ...); + virtual PromelaParserNode* value(int type, void* location, const char* value); + void dump(); + + int parseInCompound; + + PromelaParserNode* ast; + Type type; + + Event pendingException; + operator bool() const { + return ast != NULL; + } + +protected: + + void init(const std::string& expr); + void destroy(); + + void* buffer; + void* scanner; + char* input; + size_t input_length; +}; + +} + +void promela_error (void* yylloc_param, uscxml::PromelaParser* ctx, void* yyscanner, const char* err); + +#endif /* end of include guard: PROMELA_H_9AB78YB1 */ diff --git a/src/uscxml/plugins/datamodel/promela/parser/promela.l b/src/uscxml/plugins/datamodel/promela/parser/promela.l new file mode 100644 index 0000000..1edc625 --- /dev/null +++ b/src/uscxml/plugins/datamodel/promela/parser/promela.l @@ -0,0 +1,117 @@ +/* see: http://www.phpcompiler.org/articles/reentrantparser.html */ +/* see: http://spinroot.com/spin/Man/operators.html */ + + +%option yylineno +%option reentrant +%option bison-bridge +%option prefix="promela_" +%option outfile="promela.lex.yy.cpp" +%option noyywrap +%option debug +%option never-interactive nounistd +%option bison-locations + +%{ + +#include "../PromelaParser.h" +#include "promela.tab.hpp" +#define YYSTYPE PROMELA_STYPE +#define YYLTYPE PROMELA_LTYPE +#define YY_USER_INIT \ + yycolumn = yylloc->first_line = yylloc->first_column = 0; \ + yylineno = yylloc->last_line = yylloc->last_column = 0; \ + +//int yycolumn = 1; + +#define YY_USER_ACTION \ +{ \ + yylloc->first_line = yylineno; \ + yylloc->first_column = yycolumn; \ + yylloc->last_column = yycolumn + yyleng; \ + yylloc->last_line = yylineno; \ + yycolumn = yycolumn + yyleng; \ +} + +%} + +DIGIT [0-9] +ID [_a-zA-Z][_a-zA-Z0-9]* +L [a-zA-Z_] + +%% + +\/\*([^*]|\*[^/])*\*+\/ /* multiline comments */ + +bit|bool|byte|int|mtype|short|unsigned|string|auto { + yylval->value = strdup(yytext); + return PML_TYPE; +} + +len { return PML_LEN; } +false|skip|true { yylval->value = strdup(yytext); return PML_CONST; } +printf { return PML_PRINT; } +typedef { return PML_TYPEDEF; } +assert { return PML_ASSERT; } + +"!" { return PML_NEG; } +"~" { return PML_COMPL; } +"++" { return PML_INCR; } +"--" { return PML_DECR; } + +"*" { return PML_TIMES; } +"/" { return PML_DIVIDE; } +"%" { return PML_MODULO; } + +"+" { return PML_PLUS; } +"-" { return PML_MINUS; } + +"<<" { return PML_LSHIFT; } +">>" { return PML_RSHIFT; } + +"<=" { return PML_LE; } +">=" { return PML_GE; } +"<" { return PML_LT; } +">" { return PML_GT; } + +"!=" { return PML_NE; } +"==" { return PML_EQ; } + +"&" { return PML_BITAND; } +"^" { return PML_BITXOR; } +"|" { return PML_BITOR; } + + +"&&" { return PML_AND; } +"||" { return PML_OR; } + +"." { return PML_DOT; } +"," { return PML_COMMA; } +";" { return PML_SEMI; } + +"(" { return '('; } +")" { return ')'; } + +"[" { return '['; } +"]" { return ']'; } + +"{" { return '{'; } +"}" { return '}'; } + +"=" { return PML_ASGN; } + +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 */ + + +. { /*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 new file mode 100644 index 0000000..3a99921 --- /dev/null +++ b/src/uscxml/plugins/datamodel/promela/parser/promela.lex.yy.cpp @@ -0,0 +1,2598 @@ +#line 2 "promela.lex.yy.cpp" + +#line 4 "promela.lex.yy.cpp" + +#define YY_INT_ALIGNED short int + +/* A lexical scanner generated by flex */ + +/* %not-for-header */ + +/* %if-c-only */ +/* %if-not-reentrant */ +/* %endif */ +/* %endif */ +/* %ok-for-header */ + +#define FLEX_SCANNER +#define YY_FLEX_MAJOR_VERSION 2 +#define YY_FLEX_MINOR_VERSION 5 +#define YY_FLEX_SUBMINOR_VERSION 35 +#if YY_FLEX_SUBMINOR_VERSION > 0 +#define FLEX_BETA +#endif + +/* %if-c++-only */ +/* %endif */ + +/* %if-c-only */ + +/* %endif */ + +/* %if-c-only */ + +/* %endif */ + +/* First, we deal with platform-specific or compiler-specific issues. */ + +/* begin standard C headers. */ +/* %if-c-only */ +#include +#include +#include +#include +/* %endif */ + +/* %if-tables-serialization */ +/* %endif */ +/* end standard C headers. */ + +/* %if-c-or-c++ */ +/* flex integer type definitions */ + +#ifndef FLEXINT_H +#define FLEXINT_H + +/* C99 systems have . Non-C99 systems may or may not. */ + +#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L + +/* C99 says to define __STDC_LIMIT_MACROS before including stdint.h, + * if you want the limit (max/min) macros for int types. + */ +#ifndef __STDC_LIMIT_MACROS +#define __STDC_LIMIT_MACROS 1 +#endif + +#include +typedef int8_t flex_int8_t; +typedef uint8_t flex_uint8_t; +typedef int16_t flex_int16_t; +typedef uint16_t flex_uint16_t; +typedef int32_t flex_int32_t; +typedef uint32_t flex_uint32_t; +typedef uint64_t flex_uint64_t; +#else +typedef signed char flex_int8_t; +typedef short int flex_int16_t; +typedef int flex_int32_t; +typedef unsigned char flex_uint8_t; +typedef unsigned short int flex_uint16_t; +typedef unsigned int flex_uint32_t; +#endif /* ! C99 */ + +/* Limits of integral types. */ +#ifndef INT8_MIN +#define INT8_MIN (-128) +#endif +#ifndef INT16_MIN +#define INT16_MIN (-32767-1) +#endif +#ifndef INT32_MIN +#define INT32_MIN (-2147483647-1) +#endif +#ifndef INT8_MAX +#define INT8_MAX (127) +#endif +#ifndef INT16_MAX +#define INT16_MAX (32767) +#endif +#ifndef INT32_MAX +#define INT32_MAX (2147483647) +#endif +#ifndef UINT8_MAX +#define UINT8_MAX (255U) +#endif +#ifndef UINT16_MAX +#define UINT16_MAX (65535U) +#endif +#ifndef UINT32_MAX +#define UINT32_MAX (4294967295U) +#endif + +#endif /* ! FLEXINT_H */ + +/* %endif */ + +/* %if-c++-only */ +/* %endif */ + +#ifdef __cplusplus + +/* The "const" storage-class-modifier is valid. */ +#define YY_USE_CONST + +#else /* ! __cplusplus */ + +/* C99 requires __STDC__ to be defined as 1. */ +#if defined (__STDC__) + +#define YY_USE_CONST + +#endif /* defined (__STDC__) */ +#endif /* ! __cplusplus */ + +#ifdef YY_USE_CONST +#define yyconst const +#else +#define yyconst +#endif + +/* %not-for-header */ + +/* Returned upon end-of-file. */ +#define YY_NULL 0 +/* %ok-for-header */ + +/* %not-for-header */ + +/* Promotes a possibly negative, possibly signed char to an unsigned + * integer for use as an array index. If the signed char is negative, + * we want to instead treat it as an 8-bit unsigned char, hence the + * double cast. + */ +#define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c) +/* %ok-for-header */ + +/* %if-reentrant */ + +/* An opaque pointer. */ +#ifndef YY_TYPEDEF_YY_SCANNER_T +#define YY_TYPEDEF_YY_SCANNER_T +typedef void* yyscan_t; +#endif + +/* For convenience, these vars (plus the bison vars far below) + are macros in the reentrant scanner. */ +#define yyin yyg->yyin_r +#define yyout yyg->yyout_r +#define yyextra yyg->yyextra_r +#define yyleng yyg->yyleng_r +#define yytext yyg->yytext_r +#define yylineno (YY_CURRENT_BUFFER_LVALUE->yy_bs_lineno) +#define yycolumn (YY_CURRENT_BUFFER_LVALUE->yy_bs_column) +#define yy_flex_debug yyg->yy_flex_debug_r + +/* %endif */ + +/* %if-not-reentrant */ +/* %endif */ + +/* Enter a start condition. This macro really ought to take a parameter, + * but we do it the disgusting crufty way forced on us by the ()-less + * definition of BEGIN. + */ +#define BEGIN yyg->yy_start = 1 + 2 * + +/* Translate the current start state into a value that can be later handed + * to BEGIN to return to the state. The YYSTATE alias is for lex + * compatibility. + */ +#define YY_START ((yyg->yy_start - 1) / 2) +#define YYSTATE YY_START + +/* Action number for EOF rule of a given start state. */ +#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1) + +/* Special action meaning "start processing a new file". */ +#define YY_NEW_FILE promela_restart(yyin ,yyscanner ) + +#define YY_END_OF_BUFFER_CHAR 0 + +/* Size of default input buffer. */ +#ifndef YY_BUF_SIZE +#define YY_BUF_SIZE 16384 +#endif + +/* The state buf must be large enough to hold one state per character in the main buffer. + */ +#define YY_STATE_BUF_SIZE ((YY_BUF_SIZE + 2) * sizeof(yy_state_type)) + +#ifndef YY_TYPEDEF_YY_BUFFER_STATE +#define YY_TYPEDEF_YY_BUFFER_STATE +typedef struct yy_buffer_state *YY_BUFFER_STATE; +#endif + +#ifndef YY_TYPEDEF_YY_SIZE_T +#define YY_TYPEDEF_YY_SIZE_T +typedef size_t yy_size_t; +#endif + +/* %if-not-reentrant */ +/* %endif */ + +/* %if-c-only */ +/* %if-not-reentrant */ +/* %endif */ +/* %endif */ + +#define EOB_ACT_CONTINUE_SCAN 0 +#define EOB_ACT_END_OF_FILE 1 +#define EOB_ACT_LAST_MATCH 2 + +/* Note: We specifically omit the test for yy_rule_can_match_eol because it requires + * access to the local variable yy_act. Since yyless() is a macro, it would break + * existing scanners that call yyless() from OUTSIDE promela_lex. + * One obvious solution it to make yy_act a global. I tried that, and saw + * a 5% performance hit in a non-yylineno scanner, because yy_act is + * normally declared as a register variable-- so it is not worth it. + */ +#define YY_LESS_LINENO(n) \ + do { \ + yy_size_t yyl;\ + for ( yyl = n; yyl < yyleng; ++yyl )\ + if ( yytext[yyl] == '\n' )\ + --yylineno;\ + }while(0) + +/* Return all but the first "n" matched characters back to the input stream. */ +#define yyless(n) \ + do \ + { \ + /* Undo effects of setting up yytext. */ \ + int yyless_macro_arg = (n); \ + YY_LESS_LINENO(yyless_macro_arg);\ + *yy_cp = yyg->yy_hold_char; \ + YY_RESTORE_YY_MORE_OFFSET \ + yyg->yy_c_buf_p = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \ + YY_DO_BEFORE_ACTION; /* set up yytext again */ \ + } \ + while ( 0 ) + +#define unput(c) yyunput( c, yyg->yytext_ptr , yyscanner ) + +#ifndef YY_STRUCT_YY_BUFFER_STATE +#define YY_STRUCT_YY_BUFFER_STATE +struct yy_buffer_state { + /* %if-c-only */ + FILE *yy_input_file; + /* %endif */ + + /* %if-c++-only */ + /* %endif */ + + char *yy_ch_buf; /* input buffer */ + char *yy_buf_pos; /* current position in input buffer */ + + /* Size of input buffer in bytes, not including room for EOB + * characters. + */ + yy_size_t yy_buf_size; + + /* Number of characters read into yy_ch_buf, not including EOB + * characters. + */ + yy_size_t yy_n_chars; + + /* Whether we "own" the buffer - i.e., we know we created it, + * and can realloc() it to grow it, and should free() it to + * delete it. + */ + int yy_is_our_buffer; + + /* Whether this is an "interactive" input source; if so, and + * if we're using stdio for input, then we want to use getc() + * instead of fread(), to make sure we stop fetching input after + * each newline. + */ + int yy_is_interactive; + + /* Whether we're considered to be at the beginning of a line. + * If so, '^' rules will be active on the next match, otherwise + * not. + */ + int yy_at_bol; + + int yy_bs_lineno; /**< The line count. */ + int yy_bs_column; /**< The column count. */ + + /* Whether to try to fill the input buffer when we reach the + * end of it. + */ + int yy_fill_buffer; + + int yy_buffer_status; + +#define YY_BUFFER_NEW 0 +#define YY_BUFFER_NORMAL 1 + /* When an EOF's been seen but there's still some text to process + * then we mark the buffer as YY_EOF_PENDING, to indicate that we + * shouldn't try reading from the input source any more. We might + * still have a bunch of tokens to match, though, because of + * possible backing-up. + * + * When we actually see the EOF, we change the status to "new" + * (via promela_restart()), so that the user can continue scanning by + * just pointing yyin at a new input file. + */ +#define YY_BUFFER_EOF_PENDING 2 + +}; +#endif /* !YY_STRUCT_YY_BUFFER_STATE */ + +/* %if-c-only Standard (non-C++) definition */ +/* %not-for-header */ + +/* %if-not-reentrant */ +/* %endif */ +/* %ok-for-header */ + +/* %endif */ + +/* We provide macros for accessing buffer states in case in the + * future we want to put the buffer states in a more general + * "scanner state". + * + * Returns the top of the stack, or NULL. + */ +#define YY_CURRENT_BUFFER ( yyg->yy_buffer_stack \ + ? yyg->yy_buffer_stack[yyg->yy_buffer_stack_top] \ + : NULL) + +/* Same as previous macro, but useful when we know that the buffer stack is not + * NULL or when we need an lvalue. For internal use only. + */ +#define YY_CURRENT_BUFFER_LVALUE yyg->yy_buffer_stack[yyg->yy_buffer_stack_top] + +/* %if-c-only Standard (non-C++) definition */ + +/* %if-not-reentrant */ +/* %not-for-header */ + +/* %ok-for-header */ + +/* %endif */ + +void promela_restart (FILE *input_file ,yyscan_t yyscanner ); +void promela__switch_to_buffer (YY_BUFFER_STATE new_buffer ,yyscan_t yyscanner ); +YY_BUFFER_STATE promela__create_buffer (FILE *file,int size ,yyscan_t yyscanner ); +void promela__delete_buffer (YY_BUFFER_STATE b ,yyscan_t yyscanner ); +void promela__flush_buffer (YY_BUFFER_STATE b ,yyscan_t yyscanner ); +void promela_push_buffer_state (YY_BUFFER_STATE new_buffer ,yyscan_t yyscanner ); +void promela_pop_buffer_state (yyscan_t yyscanner ); + +static void promela_ensure_buffer_stack (yyscan_t yyscanner ); +static void promela__load_buffer_state (yyscan_t yyscanner ); +static void promela__init_buffer (YY_BUFFER_STATE b,FILE *file ,yyscan_t yyscanner ); + +#define YY_FLUSH_BUFFER promela__flush_buffer(YY_CURRENT_BUFFER ,yyscanner) + +YY_BUFFER_STATE promela__scan_buffer (char *base,yy_size_t size ,yyscan_t yyscanner ); +YY_BUFFER_STATE promela__scan_string (yyconst char *yy_str ,yyscan_t yyscanner ); +YY_BUFFER_STATE promela__scan_bytes (yyconst char *bytes,yy_size_t len ,yyscan_t yyscanner ); + +/* %endif */ + +void *promela_alloc (yy_size_t ,yyscan_t yyscanner ); +void *promela_realloc (void *,yy_size_t ,yyscan_t yyscanner ); +void promela_free (void * ,yyscan_t yyscanner ); + +#define yy_new_buffer promela__create_buffer + +#define yy_set_interactive(is_interactive) \ + { \ + if ( ! YY_CURRENT_BUFFER ){ \ + promela_ensure_buffer_stack (yyscanner); \ + YY_CURRENT_BUFFER_LVALUE = \ + promela__create_buffer(yyin,YY_BUF_SIZE ,yyscanner); \ + } \ + YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \ + } + +#define yy_set_bol(at_bol) \ + { \ + if ( ! YY_CURRENT_BUFFER ){\ + promela_ensure_buffer_stack (yyscanner); \ + YY_CURRENT_BUFFER_LVALUE = \ + promela__create_buffer(yyin,YY_BUF_SIZE ,yyscanner); \ + } \ + YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \ + } + +#define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol) + +/* %% [1.0] yytext/yyin/yyout/yy_state_type/yylineno etc. def's & init go here */ + +#define promela_wrap(n) 1 +#define YY_SKIP_YYWRAP + +#define FLEX_DEBUG + +typedef unsigned char YY_CHAR; + +typedef int yy_state_type; + +#define yytext_ptr yytext_r + +/* %if-c-only Standard (non-C++) definition */ + +static yy_state_type yy_get_previous_state (yyscan_t yyscanner ); +static yy_state_type yy_try_NUL_trans (yy_state_type current_state ,yyscan_t yyscanner); +static int yy_get_next_buffer (yyscan_t yyscanner ); +static void yy_fatal_error (yyconst char msg[] ,yyscan_t yyscanner ); + +/* %endif */ + +/* Done after the current pattern has been matched and before the + * corresponding action - sets up yytext. + */ +#define YY_DO_BEFORE_ACTION \ + yyg->yytext_ptr = yy_bp; \ +/* %% [2.0] code to fiddle yytext and yyleng for yymore() goes here \ */\ + yyleng = (yy_size_t) (yy_cp - yy_bp); \ + yyg->yy_hold_char = *yy_cp; \ + *yy_cp = '\0'; \ +/* %% [3.0] code to copy yytext_ptr to yytext[] goes here, if %array \ */\ + 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 46 +#define YY_END_OF_BUFFER 47 +/* 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[126] = { + 0, + 0, 0, 47, 45, 44, 44, 8, 45, 14, 25, + 45, 33, 34, 12, 15, 31, 16, 30, 13, 42, + 32, 21, 39, 22, 43, 43, 35, 36, 26, 43, + 43, 43, 43, 43, 43, 43, 43, 43, 43, 37, + 27, 38, 9, 44, 23, 0, 40, 0, 28, 0, + 41, 0, 10, 11, 0, 42, 17, 19, 24, 20, + 18, 43, 0, 0, 43, 43, 43, 43, 43, 43, + 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, + 29, 0, 41, 0, 0, 0, 43, 43, 2, 43, + 43, 43, 3, 43, 43, 43, 43, 43, 43, 43, + + 43, 0, 1, 43, 43, 43, 43, 43, 4, 43, + 43, 43, 1, 43, 43, 43, 43, 43, 7, 5, + 43, 43, 6, 43, 0 +} ; + +static yyconst flex_int32_t yy_ec[256] = { + 0, + 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 2, 4, 5, 1, 1, 6, 7, 8, 9, + 10, 11, 12, 13, 14, 15, 16, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 1, 18, 19, + 20, 21, 1, 1, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 23, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, + 24, 25, 26, 27, 22, 1, 28, 29, 22, 30, + + 31, 32, 33, 34, 35, 22, 36, 37, 38, 39, + 40, 41, 22, 42, 43, 44, 45, 22, 22, 22, + 46, 22, 47, 48, 49, 50, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1 +} ; + +static yyconst flex_int32_t yy_meta[51] = { + 0, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, + 1, 2, 2, 1, 1, 1, 1, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 1, 1, 1, 1 +} ; + +static yyconst flex_int16_t yy_base[131] = { + 0, + 0, 0, 172, 173, 49, 51, 151, 50, 173, 163, + 48, 173, 173, 173, 157, 173, 154, 173, 156, 149, + 173, 38, 145, 39, 0, 56, 173, 173, 173, 20, + 31, 136, 124, 131, 117, 118, 34, 30, 120, 173, + 110, 173, 173, 77, 173, 57, 173, 154, 173, 59, + 173, 66, 173, 173, 145, 138, 173, 173, 173, 173, + 173, 0, 76, 75, 111, 109, 108, 111, 106, 112, + 104, 108, 100, 110, 104, 108, 100, 96, 99, 96, + 173, 77, 78, 84, 127, 77, 106, 96, 0, 98, + 103, 90, 0, 91, 92, 88, 88, 93, 96, 95, + + 90, 78, 173, 82, 92, 91, 77, 76, 0, 80, + 88, 75, 96, 62, 73, 71, 68, 59, 0, 0, + 65, 65, 0, 65, 173, 109, 111, 88, 113, 115 +} ; + +static yyconst flex_int16_t yy_def[131] = { + 0, + 125, 1, 125, 125, 125, 125, 125, 126, 125, 125, + 127, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 128, 128, 125, 125, 125, 128, + 128, 128, 128, 128, 128, 128, 128, 128, 128, 125, + 125, 125, 125, 125, 125, 126, 125, 126, 125, 127, + 125, 129, 125, 125, 130, 125, 125, 125, 125, 125, + 125, 128, 126, 127, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, + 125, 127, 127, 129, 130, 130, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, + + 128, 130, 125, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 130, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 0, 125, 125, 125, 125, 125 +} ; + +static yyconst flex_int16_t yy_nxt[224] = { + 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, 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, 47, 65, 64, 66, 67, 51, 75, 50, 76, + 68, 78, 52, 83, 48, 79, 69, 77, 44, 44, + 47, 48, 51, 52, 51, 51, 50, 102, 86, 62, + 84, 83, 103, 113, 89, 124, 123, 122, 121, 52, + + 48, 52, 52, 89, 120, 119, 86, 118, 84, 46, + 46, 50, 50, 82, 82, 85, 85, 117, 116, 89, + 115, 89, 109, 114, 112, 111, 109, 110, 109, 108, + 107, 106, 105, 89, 89, 89, 104, 86, 101, 100, + 99, 98, 97, 96, 95, 94, 93, 89, 92, 91, + 90, 89, 88, 87, 56, 86, 125, 81, 80, 74, + 73, 72, 71, 70, 59, 56, 55, 54, 53, 49, + 45, 125, 3, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125 +} ; + +static yyconst flex_int16_t yy_chk[224] = { + 0, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 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, + 26, 46, 30, 26, 30, 31, 50, 37, 52, 37, + 31, 38, 11, 52, 8, 38, 31, 37, 44, 44, + 63, 46, 64, 50, 82, 83, 84, 86, 102, 128, + 52, 84, 86, 102, 124, 122, 121, 118, 117, 64, + + 63, 82, 83, 116, 115, 114, 113, 112, 84, 126, + 126, 127, 127, 129, 129, 130, 130, 111, 110, 108, + 107, 106, 105, 104, 101, 100, 99, 98, 97, 96, + 95, 94, 92, 91, 90, 88, 87, 85, 80, 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, 23, 20, 19, 17, 15, 10, + 7, 3, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125 +} ; + +/* Table of booleans, true if rule could match eol. */ +static yyconst flex_int32_t yy_rule_can_match_eol[47] = { + 0, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 1, 0, 0, 1, 0, 0, +}; + +static yyconst flex_int16_t yy_rule_linenum[46] = { + 0, + 44, 46, 51, 52, 53, 54, 55, 57, 58, 59, + 60, 62, 63, 64, 66, 67, 69, 70, 72, 73, + 74, 75, 77, 78, 80, 81, 82, 85, 86, 88, + 89, 90, 92, 93, 95, 96, 98, 99, 101, 103, + 106, 111, 112, 114, 117 +} ; + +/* The intent behind this definition is that it'll catch + * any uses of REJECT which flex missed. + */ +#define REJECT reject_used_but_not_detected +#define yymore() yymore_used_but_not_detected +#define YY_MORE_ADJ 0 +#define YY_RESTORE_YY_MORE_OFFSET +#line 1 "promela.l" +/* see: http://www.phpcompiler.org/articles/reentrantparser.html */ +/* see: http://spinroot.com/spin/Man/operators.html */ +#define YY_NO_UNISTD_H 1 +#line 16 "promela.l" + +#include "../PromelaParser.h" +#include "promela.tab.hpp" +#define YYSTYPE PROMELA_STYPE +#define YYLTYPE PROMELA_LTYPE +#define YY_USER_INIT \ + yycolumn = yylloc->first_line = yylloc->first_column = 0; \ + yylineno = yylloc->last_line = yylloc->last_column = 0; \ + +//int yycolumn = 1; + +#define YY_USER_ACTION \ +{ \ + yylloc->first_line = yylineno; \ + yylloc->first_column = yycolumn; \ + yylloc->last_column = yycolumn + yyleng; \ + yylloc->last_line = yylineno; \ + yycolumn = yycolumn + yyleng; \ +} + +#line 661 "promela.lex.yy.cpp" + +#define INITIAL 0 + +#ifndef YY_NO_UNISTD_H +/* Special case for "unistd.h", since it is non-ANSI. We include it way + * down here because we want the user's section 1 to have been scanned first. + * The user has a chance to override it with an option. + */ +/* %if-c-only */ +#include +/* %endif */ +/* %if-c++-only */ +/* %endif */ +#endif + +#ifndef YY_EXTRA_TYPE +#define YY_EXTRA_TYPE void * +#endif + +/* %if-c-only Reentrant structure and macros (non-C++). */ +/* %if-reentrant */ + +/* Holds the entire state of the reentrant scanner. */ +struct yyguts_t { + + /* User-defined. Not touched by flex. */ + YY_EXTRA_TYPE yyextra_r; + + /* The rest are the same as the globals declared in the non-reentrant scanner. */ + FILE *yyin_r, *yyout_r; + size_t yy_buffer_stack_top; /**< index of top of stack. */ + size_t yy_buffer_stack_max; /**< capacity of stack. */ + YY_BUFFER_STATE * yy_buffer_stack; /**< Stack as an array. */ + char yy_hold_char; + yy_size_t yy_n_chars; + yy_size_t yyleng_r; + char *yy_c_buf_p; + int yy_init; + int yy_start; + int yy_did_buffer_switch_on_eof; + int yy_start_stack_ptr; + int yy_start_stack_depth; + int *yy_start_stack; + yy_state_type yy_last_accepting_state; + char* yy_last_accepting_cpos; + + int yylineno_r; + int yy_flex_debug_r; + + char *yytext_r; + int yy_more_flag; + int yy_more_len; + + YYSTYPE * yylval_r; + + YYLTYPE * yylloc_r; + +}; /* end struct yyguts_t */ + +/* %if-c-only */ + +static int yy_init_globals (yyscan_t yyscanner ); + +/* %endif */ + +/* %if-reentrant */ + +/* This must go here because YYSTYPE and YYLTYPE are included + * from bison output in section 1.*/ +# define yylval yyg->yylval_r + +# define yylloc yyg->yylloc_r + +int promela_lex_init (yyscan_t* scanner); + +int promela_lex_init_extra (YY_EXTRA_TYPE user_defined,yyscan_t* scanner); + +/* %endif */ + +/* %endif End reentrant structures and macros. */ + +/* Accessor methods to globals. + These are made visible to non-reentrant scanners for convenience. */ + +int promela_lex_destroy (yyscan_t yyscanner ); + +int promela_get_debug (yyscan_t yyscanner ); + +void promela_set_debug (int debug_flag ,yyscan_t yyscanner ); + +YY_EXTRA_TYPE promela_get_extra (yyscan_t yyscanner ); + +void promela_set_extra (YY_EXTRA_TYPE user_defined ,yyscan_t yyscanner ); + +FILE *promela_get_in (yyscan_t yyscanner ); + +void promela_set_in (FILE * in_str ,yyscan_t yyscanner ); + +FILE *promela_get_out (yyscan_t yyscanner ); + +void promela_set_out (FILE * out_str ,yyscan_t yyscanner ); + +yy_size_t promela_get_leng (yyscan_t yyscanner ); + +char *promela_get_text (yyscan_t yyscanner ); + +int promela_get_lineno (yyscan_t yyscanner ); + +void promela_set_lineno (int line_number ,yyscan_t yyscanner ); + +/* %if-bison-bridge */ + +YYSTYPE * promela_get_lval (yyscan_t yyscanner ); + +void promela_set_lval (YYSTYPE * yylval_param ,yyscan_t yyscanner ); + +YYLTYPE *promela_get_lloc (yyscan_t yyscanner ); + +void promela_set_lloc (YYLTYPE * yylloc_param ,yyscan_t yyscanner ); + +/* %endif */ + +/* Macros after this point can all be overridden by user definitions in + * section 1. + */ + +#ifndef YY_SKIP_YYWRAP +#ifdef __cplusplus +extern "C" int promela_wrap (yyscan_t yyscanner ); +#else +extern int promela_wrap (yyscan_t yyscanner ); +#endif +#endif + +/* %not-for-header */ + +static void yyunput (int c,char *buf_ptr ,yyscan_t yyscanner); + +/* %ok-for-header */ + +/* %endif */ + +#ifndef yytext_ptr +static void yy_flex_strncpy (char *,yyconst char *,int ,yyscan_t yyscanner); +#endif + +#ifdef YY_NEED_STRLEN +static int yy_flex_strlen (yyconst char * ,yyscan_t yyscanner); +#endif + +#ifndef YY_NO_INPUT +/* %if-c-only Standard (non-C++) definition */ +/* %not-for-header */ + +#ifdef __cplusplus +static int yyinput (yyscan_t yyscanner ); +#else +static int input (yyscan_t yyscanner ); +#endif +/* %ok-for-header */ + +/* %endif */ +#endif + +/* %if-c-only */ + +/* %endif */ + +/* Amount of stuff to slurp up with each read. */ +#ifndef YY_READ_BUF_SIZE +#define YY_READ_BUF_SIZE 8192 +#endif + +/* Copy whatever the last rule matched to the standard output. */ +#ifndef ECHO +/* %if-c-only Standard (non-C++) definition */ +/* This used to be an fputs(), but since the string might contain NUL's, + * we now use fwrite(). + */ +#define ECHO fwrite( yytext, yyleng, 1, yyout ) +/* %endif */ +/* %if-c++-only C++ definition */ +/* %endif */ +#endif + +/* Gets input and stuffs it into "buf". number of characters read, or YY_NULL, + * is returned in "result". + */ +#ifndef YY_INPUT +#define YY_INPUT(buf,result,max_size) \ +/* %% [5.0] fread()/read() definition of YY_INPUT goes here unless we're doing C++ \ */\ + if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \ + { \ + int c = '*'; \ + yy_size_t n; \ + for ( n = 0; n < max_size && \ + (c = getc( yyin )) != EOF && c != '\n'; ++n ) \ + buf[n] = (char) c; \ + if ( c == '\n' ) \ + buf[n++] = (char) c; \ + if ( c == EOF && ferror( yyin ) ) \ + YY_FATAL_ERROR( "input in flex scanner failed" ); \ + result = n; \ + } \ + else \ + { \ + errno=0; \ + while ( (result = fread(buf, 1, max_size, yyin))==0 && ferror(yyin)) \ + { \ + if( errno != EINTR) \ + { \ + YY_FATAL_ERROR( "input in flex scanner failed" ); \ + break; \ + } \ + errno=0; \ + clearerr(yyin); \ + } \ + }\ +\ +/* %if-c++-only C++ definition \ */\ +/* %endif */ + +#endif + +/* No semi-colon after return; correct usage is to write "yyterminate();" - + * we don't want an extra ';' after the "return" because that will cause + * some compilers to complain about unreachable statements. + */ +#ifndef yyterminate +#define yyterminate() return YY_NULL +#endif + +/* Number of entries by which start-condition stack grows. */ +#ifndef YY_START_STACK_INCR +#define YY_START_STACK_INCR 25 +#endif + +/* Report a fatal error. */ +#ifndef YY_FATAL_ERROR +/* %if-c-only */ +#define YY_FATAL_ERROR(msg) yy_fatal_error( msg , yyscanner) +/* %endif */ +/* %if-c++-only */ +/* %endif */ +#endif + +/* %if-tables-serialization structures and prototypes */ +/* %not-for-header */ + +/* %ok-for-header */ + +/* %not-for-header */ + +/* %tables-yydmap generated elements */ +/* %endif */ +/* end tables serialization structures and prototypes */ + +/* %ok-for-header */ + +/* Default declaration of generated scanner - a define so the user can + * easily add parameters. + */ +#ifndef YY_DECL +#define YY_DECL_IS_OURS 1 +/* %if-c-only Standard (non-C++) definition */ + +extern int promela_lex \ +(YYSTYPE * yylval_param,YYLTYPE * yylloc_param ,yyscan_t yyscanner); + +#define YY_DECL int promela_lex \ + (YYSTYPE * yylval_param, YYLTYPE * yylloc_param , yyscan_t yyscanner) +/* %endif */ +/* %if-c++-only C++ definition */ +/* %endif */ +#endif /* !YY_DECL */ + +/* Code executed at the beginning of each rule, after yytext and yyleng + * have been set up. + */ +#ifndef YY_USER_ACTION +#define YY_USER_ACTION +#endif + +/* Code executed at the end of each rule. */ +#ifndef YY_BREAK +#define YY_BREAK break; +#endif + +/* %% [6.0] YY_RULE_SETUP definition goes here */ +#define YY_RULE_SETUP \ + YY_USER_ACTION + +/* %not-for-header */ + +/** The main scanner function which does all the work. + */ +YY_DECL { + register yy_state_type yy_current_state; + register char *yy_cp, *yy_bp; + register int yy_act; + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + + /* %% [7.0] user's declarations go here */ +#line 42 "promela.l" + + +#line 970 "promela.lex.yy.cpp" + + yylval = yylval_param; + + yylloc = yylloc_param; + + if ( !yyg->yy_init ) { + yyg->yy_init = 1; + +#ifdef YY_USER_INIT + YY_USER_INIT; +#endif + + if ( ! yyg->yy_start ) + yyg->yy_start = 1; /* first start state */ + + if ( ! yyin ) + /* %if-c-only */ + yyin = stdin; + /* %endif */ + /* %if-c++-only */ + /* %endif */ + + if ( ! yyout ) + /* %if-c-only */ + yyout = stdout; + /* %endif */ + /* %if-c++-only */ + /* %endif */ + + if ( ! YY_CURRENT_BUFFER ) { + promela_ensure_buffer_stack (yyscanner); + YY_CURRENT_BUFFER_LVALUE = + promela__create_buffer(yyin,YY_BUF_SIZE ,yyscanner); + } + + promela__load_buffer_state(yyscanner ); + } + + while ( 1 ) { /* loops until end-of-file is reached */ + /* %% [8.0] yymore()-related code goes here */ + yy_cp = yyg->yy_c_buf_p; + + /* Support of yytext. */ + *yy_cp = yyg->yy_hold_char; + + /* yy_bp points to the position in yy_ch_buf of the start of + * the current run. + */ + yy_bp = yy_cp; + + /* %% [9.0] code to set up and find next match goes here */ + yy_current_state = yyg->yy_start; +yy_match: + do { + register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)]; + if ( yy_accept[yy_current_state] ) { + yyg->yy_last_accepting_state = yy_current_state; + yyg->yy_last_accepting_cpos = yy_cp; + } + 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 >= 126 ) + 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 != 125 ); + yy_cp = yyg->yy_last_accepting_cpos; + yy_current_state = yyg->yy_last_accepting_state; + +yy_find_action: + /* %% [10.0] code to find the action number goes here */ + yy_act = yy_accept[yy_current_state]; + + YY_DO_BEFORE_ACTION; + + /* %% [11.0] code for yylineno update goes here */ + + if ( yy_act != YY_END_OF_BUFFER && yy_rule_can_match_eol[yy_act] ) { + yy_size_t yyl; + for ( yyl = 0; yyl < yyleng; ++yyl ) + if ( yytext[yyl] == '\n' ) + + do { + yylineno++; + yycolumn=0; + } while(0) + ; + } + +do_action: /* This label is used only to access EOF actions. */ + + /* %% [12.0] debug code goes here */ + if ( yy_flex_debug ) { + if ( yy_act == 0 ) + fprintf( stderr, "--scanner backing up\n" ); + else if ( yy_act < 46 ) + fprintf( stderr, "--accepting rule at line %ld (\"%s\")\n", + (long)yy_rule_linenum[yy_act], yytext ); + else if ( yy_act == 46 ) + fprintf( stderr, "--accepting default rule (\"%s\")\n", + yytext ); + else if ( yy_act == 47 ) + fprintf( stderr, "--(end of buffer or a NUL)\n" ); + else + fprintf( stderr, "--EOF (start condition %d)\n", YY_START ); + } + + switch ( yy_act ) { + /* beginning of action switch */ + /* %% [13.0] actions go here */ + case 0: /* must back up */ + /* undo the effects of YY_DO_BEFORE_ACTION */ + *yy_cp = yyg->yy_hold_char; + yy_cp = yyg->yy_last_accepting_cpos; + yy_current_state = yyg->yy_last_accepting_state; + goto yy_find_action; + + case 1: + /* rule 1 can match eol */ + YY_RULE_SETUP +#line 44 "promela.l" + /* multiline comments */ + YY_BREAK + case 2: + YY_RULE_SETUP +#line 46 "promela.l" + { + yylval->value = strdup(yytext); + return PML_TYPE; + } + YY_BREAK + case 3: + YY_RULE_SETUP +#line 51 "promela.l" + { return PML_LEN; } + YY_BREAK + case 4: + YY_RULE_SETUP +#line 52 "promela.l" + { yylval->value = strdup(yytext); return PML_CONST; } + YY_BREAK + case 5: + YY_RULE_SETUP +#line 53 "promela.l" + { return PML_PRINT; } + YY_BREAK + case 6: + YY_RULE_SETUP +#line 54 "promela.l" + { return PML_TYPEDEF; } + YY_BREAK + case 7: + YY_RULE_SETUP +#line 55 "promela.l" + { return PML_ASSERT; } + YY_BREAK + case 8: + YY_RULE_SETUP +#line 57 "promela.l" + { return PML_NEG; } + YY_BREAK + case 9: + YY_RULE_SETUP +#line 58 "promela.l" + { return PML_COMPL; } + YY_BREAK + case 10: + YY_RULE_SETUP +#line 59 "promela.l" + { return PML_INCR; } + YY_BREAK + case 11: + YY_RULE_SETUP +#line 60 "promela.l" + { return PML_DECR; } + YY_BREAK + case 12: + YY_RULE_SETUP +#line 62 "promela.l" + { return PML_TIMES; } + YY_BREAK + case 13: + YY_RULE_SETUP +#line 63 "promela.l" + { return PML_DIVIDE; } + YY_BREAK + case 14: + YY_RULE_SETUP +#line 64 "promela.l" + { return PML_MODULO; } + YY_BREAK + case 15: + YY_RULE_SETUP +#line 66 "promela.l" + { return PML_PLUS; } + YY_BREAK + case 16: + YY_RULE_SETUP +#line 67 "promela.l" + { return PML_MINUS; } + YY_BREAK + case 17: + YY_RULE_SETUP +#line 69 "promela.l" + { return PML_LSHIFT; } + YY_BREAK + case 18: + YY_RULE_SETUP +#line 70 "promela.l" + { return PML_RSHIFT; } + YY_BREAK + case 19: + YY_RULE_SETUP +#line 72 "promela.l" + { return PML_LE; } + YY_BREAK + case 20: + YY_RULE_SETUP +#line 73 "promela.l" + { return PML_GE; } + YY_BREAK + case 21: + YY_RULE_SETUP +#line 74 "promela.l" + { return PML_LT; } + YY_BREAK + case 22: + YY_RULE_SETUP +#line 75 "promela.l" + { return PML_GT; } + YY_BREAK + case 23: + YY_RULE_SETUP +#line 77 "promela.l" + { return PML_NE; } + YY_BREAK + case 24: + YY_RULE_SETUP +#line 78 "promela.l" + { return PML_EQ; } + YY_BREAK + case 25: + YY_RULE_SETUP +#line 80 "promela.l" + { return PML_BITAND; } + YY_BREAK + case 26: + YY_RULE_SETUP +#line 81 "promela.l" + { return PML_BITXOR; } + YY_BREAK + case 27: + YY_RULE_SETUP +#line 82 "promela.l" + { return PML_BITOR; } + YY_BREAK + case 28: + YY_RULE_SETUP +#line 85 "promela.l" + { return PML_AND; } + YY_BREAK + case 29: + YY_RULE_SETUP +#line 86 "promela.l" + { return PML_OR; } + YY_BREAK + case 30: + YY_RULE_SETUP +#line 88 "promela.l" + { return PML_DOT; } + YY_BREAK + case 31: + YY_RULE_SETUP +#line 89 "promela.l" + { return PML_COMMA; } + YY_BREAK + case 32: + YY_RULE_SETUP +#line 90 "promela.l" + { return PML_SEMI; } + YY_BREAK + case 33: + YY_RULE_SETUP +#line 92 "promela.l" + { return '('; } + YY_BREAK + case 34: + YY_RULE_SETUP +#line 93 "promela.l" + { return ')'; } + YY_BREAK + case 35: + YY_RULE_SETUP +#line 95 "promela.l" + { return '['; } + YY_BREAK + case 36: + YY_RULE_SETUP +#line 96 "promela.l" + { return ']'; } + YY_BREAK + case 37: + YY_RULE_SETUP +#line 98 "promela.l" + { return '{'; } + YY_BREAK + case 38: + YY_RULE_SETUP +#line 99 "promela.l" + { return '}'; } + YY_BREAK + case 39: + YY_RULE_SETUP +#line 101 "promela.l" + { return PML_ASGN; } + YY_BREAK + case 40: + /* rule 40 can match eol */ + YY_RULE_SETUP +#line 103 "promela.l" + { yylval->value = strdup(yytext); return(PML_STRING); } + YY_BREAK + case 41: + /* rule 41 can match eol */ + YY_RULE_SETUP +#line 106 "promela.l" + { + /* Non PROMELA extension for single quoted string literals */ + yylval->value = strdup(yytext); + return(PML_STRING); + } + YY_BREAK + case 42: + YY_RULE_SETUP +#line 111 "promela.l" + { yylval->value = strdup(yytext); return PML_CONST; } + YY_BREAK + case 43: + YY_RULE_SETUP +#line 112 "promela.l" + { yylval->value = strdup(yytext); return PML_NAME; } + YY_BREAK + case 44: + /* rule 44 can match eol */ + YY_RULE_SETUP +#line 114 "promela.l" + /* eat up whitespace */ + YY_BREAK + case 45: + YY_RULE_SETUP +#line 117 "promela.l" + { /*printf( "Unrecognized character: %s\n", yytext ); */ } + YY_BREAK + case 46: + YY_RULE_SETUP +#line 118 "promela.l" + ECHO; + YY_BREAK +#line 1336 "promela.lex.yy.cpp" + case YY_STATE_EOF(INITIAL): + yyterminate(); + + case YY_END_OF_BUFFER: { + /* Amount of text matched not including the EOB char. */ + int yy_amount_of_matched_text = (int) (yy_cp - yyg->yytext_ptr) - 1; + + /* Undo the effects of YY_DO_BEFORE_ACTION. */ + *yy_cp = yyg->yy_hold_char; + YY_RESTORE_YY_MORE_OFFSET + + if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_NEW ) { + /* We're scanning a new file or input source. It's + * possible that this happened because the user + * just pointed yyin at a new source and called + * promela_lex(). If so, then we have to assure + * consistency between YY_CURRENT_BUFFER and our + * globals. Here is the right place to do so, because + * this is the first action (other than possibly a + * back-up) that will match for the new input source. + */ + yyg->yy_n_chars = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; + YY_CURRENT_BUFFER_LVALUE->yy_input_file = yyin; + YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL; + } + + /* Note that here we test for yy_c_buf_p "<=" to the position + * of the first EOB in the buffer, since yy_c_buf_p will + * already have been incremented past the NUL character + * (since all states make transitions on EOB to the + * end-of-buffer state). Contrast this with the test + * in input(). + */ + if ( yyg->yy_c_buf_p <= &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars] ) { + /* This was really a NUL. */ + yy_state_type yy_next_state; + + yyg->yy_c_buf_p = yyg->yytext_ptr + yy_amount_of_matched_text; + + yy_current_state = yy_get_previous_state( yyscanner ); + + /* Okay, we're now positioned to make the NUL + * transition. We couldn't have + * yy_get_previous_state() go ahead and do it + * for us because it doesn't know how to deal + * with the possibility of jamming (and we don't + * want to build jamming into it because then it + * will run more slowly). + */ + + yy_next_state = yy_try_NUL_trans( yy_current_state , yyscanner); + + yy_bp = yyg->yytext_ptr + YY_MORE_ADJ; + + if ( yy_next_state ) { + /* Consume the NUL. */ + yy_cp = ++yyg->yy_c_buf_p; + yy_current_state = yy_next_state; + goto yy_match; + } + + else { + /* %% [14.0] code to do back-up for compressed tables and set up yy_cp goes here */ + yy_cp = yyg->yy_last_accepting_cpos; + yy_current_state = yyg->yy_last_accepting_state; + goto yy_find_action; + } + } + + else switch ( yy_get_next_buffer( yyscanner ) ) { + case EOB_ACT_END_OF_FILE: { + yyg->yy_did_buffer_switch_on_eof = 0; + + if ( promela_wrap(yyscanner ) ) { + /* Note: because we've taken care in + * yy_get_next_buffer() to have set up + * yytext, we can now set up + * yy_c_buf_p so that if some total + * hoser (like flex itself) wants to + * call the scanner after we return the + * YY_NULL, it'll still work - another + * YY_NULL will get returned. + */ + yyg->yy_c_buf_p = yyg->yytext_ptr + YY_MORE_ADJ; + + yy_act = YY_STATE_EOF(YY_START); + goto do_action; + } + + else { + if ( ! yyg->yy_did_buffer_switch_on_eof ) + YY_NEW_FILE; + } + break; + } + + case EOB_ACT_CONTINUE_SCAN: + yyg->yy_c_buf_p = + yyg->yytext_ptr + yy_amount_of_matched_text; + + yy_current_state = yy_get_previous_state( yyscanner ); + + yy_cp = yyg->yy_c_buf_p; + yy_bp = yyg->yytext_ptr + YY_MORE_ADJ; + goto yy_match; + + case EOB_ACT_LAST_MATCH: + yyg->yy_c_buf_p = + &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars]; + + yy_current_state = yy_get_previous_state( yyscanner ); + + yy_cp = yyg->yy_c_buf_p; + yy_bp = yyg->yytext_ptr + YY_MORE_ADJ; + goto yy_find_action; + } + break; + } + + default: + YY_FATAL_ERROR( + "fatal flex scanner internal error--no action found" ); + } /* end of action switch */ + } /* end of scanning one token */ +} /* end of promela_lex */ +/* %ok-for-header */ + +/* %if-c++-only */ +/* %not-for-header */ + +/* %ok-for-header */ + +/* %endif */ + +/* yy_get_next_buffer - try to read in a new buffer + * + * Returns a code representing an action: + * EOB_ACT_LAST_MATCH - + * EOB_ACT_CONTINUE_SCAN - continue scanning from current position + * EOB_ACT_END_OF_FILE - end of file + */ +/* %if-c-only */ +static int yy_get_next_buffer (yyscan_t yyscanner) +/* %endif */ +/* %if-c++-only */ +/* %endif */ +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + register char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf; + register char *source = yyg->yytext_ptr; + register int number_to_move, i; + int ret_val; + + if ( yyg->yy_c_buf_p > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars + 1] ) + YY_FATAL_ERROR( + "fatal flex scanner internal error--end of buffer missed" ); + + if ( YY_CURRENT_BUFFER_LVALUE->yy_fill_buffer == 0 ) { + /* Don't try to fill the buffer, so this is an EOF. */ + if ( yyg->yy_c_buf_p - yyg->yytext_ptr - YY_MORE_ADJ == 1 ) { + /* We matched a single character, the EOB, so + * treat this as a final EOF. + */ + return EOB_ACT_END_OF_FILE; + } + + else { + /* We matched some text prior to the EOB, first + * process it. + */ + return EOB_ACT_LAST_MATCH; + } + } + + /* Try to read more data. */ + + /* First move last chars to start of buffer. */ + number_to_move = (int) (yyg->yy_c_buf_p - yyg->yytext_ptr) - 1; + + for ( i = 0; i < number_to_move; ++i ) + *(dest++) = *(source++); + + if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_EOF_PENDING ) + /* don't do the read, it's not guaranteed to return an EOF, + * just force an EOF + */ + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars = 0; + + else { + yy_size_t num_to_read = + YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1; + + while ( num_to_read <= 0 ) { + /* Not enough room in the buffer - grow it. */ + + /* just a shorter name for the current buffer */ + YY_BUFFER_STATE b = YY_CURRENT_BUFFER; + + int yy_c_buf_p_offset = + (int) (yyg->yy_c_buf_p - b->yy_ch_buf); + + if ( b->yy_is_our_buffer ) { + yy_size_t new_size = b->yy_buf_size * 2; + + if ( new_size <= 0 ) + b->yy_buf_size += b->yy_buf_size / 8; + else + b->yy_buf_size *= 2; + + b->yy_ch_buf = (char *) + /* Include room in for 2 EOB chars. */ + promela_realloc((void *) b->yy_ch_buf,b->yy_buf_size + 2 ,yyscanner ); + } else + /* Can't grow it, we don't own it. */ + b->yy_ch_buf = 0; + + if ( ! b->yy_ch_buf ) + YY_FATAL_ERROR( + "fatal error - scanner input buffer overflow" ); + + yyg->yy_c_buf_p = &b->yy_ch_buf[yy_c_buf_p_offset]; + + num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size - + number_to_move - 1; + + } + + if ( num_to_read > YY_READ_BUF_SIZE ) + num_to_read = YY_READ_BUF_SIZE; + + /* Read in more data. */ + YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]), + yyg->yy_n_chars, num_to_read ); + + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars; + } + + if ( yyg->yy_n_chars == 0 ) { + if ( number_to_move == YY_MORE_ADJ ) { + ret_val = EOB_ACT_END_OF_FILE; + promela_restart(yyin ,yyscanner); + } + + else { + ret_val = EOB_ACT_LAST_MATCH; + YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = + YY_BUFFER_EOF_PENDING; + } + } + + else + ret_val = EOB_ACT_CONTINUE_SCAN; + + if ((yy_size_t) (yyg->yy_n_chars + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) { + /* Extend the array by 50%, plus the number we really need. */ + yy_size_t new_size = yyg->yy_n_chars + number_to_move + (yyg->yy_n_chars >> 1); + YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) promela_realloc((void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf,new_size ,yyscanner ); + if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf ) + YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" ); + } + + yyg->yy_n_chars += number_to_move; + YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars] = YY_END_OF_BUFFER_CHAR; + YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars + 1] = YY_END_OF_BUFFER_CHAR; + + yyg->yytext_ptr = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[0]; + + return ret_val; +} + +/* yy_get_previous_state - get the state just before the EOB char was reached */ + +/* %if-c-only */ +/* %not-for-header */ + +static yy_state_type yy_get_previous_state (yyscan_t yyscanner) +/* %endif */ +/* %if-c++-only */ +/* %endif */ +{ + register yy_state_type yy_current_state; + register char *yy_cp; + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + + /* %% [15.0] code to get the start state into yy_current_state goes here */ + yy_current_state = yyg->yy_start; + + for ( yy_cp = yyg->yytext_ptr + YY_MORE_ADJ; yy_cp < yyg->yy_c_buf_p; ++yy_cp ) { + /* %% [16.0] code to find the next state goes here */ + register YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1); + if ( yy_accept[yy_current_state] ) { + yyg->yy_last_accepting_state = yy_current_state; + yyg->yy_last_accepting_cpos = yy_cp; + } + 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 >= 126 ) + yy_c = yy_meta[(unsigned int) yy_c]; + } + yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; + } + + return yy_current_state; +} + +/* yy_try_NUL_trans - try to make a transition on the NUL character + * + * synopsis + * next_state = yy_try_NUL_trans( current_state ); + */ +/* %if-c-only */ +static yy_state_type yy_try_NUL_trans (yy_state_type yy_current_state , yyscan_t yyscanner) +/* %endif */ +/* %if-c++-only */ +/* %endif */ +{ + register int yy_is_jam; + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; /* This var may be unused depending upon options. */ + /* %% [17.0] code to find the next state, and perhaps do backing up, goes here */ + register char *yy_cp = yyg->yy_c_buf_p; + + register YY_CHAR yy_c = 1; + if ( yy_accept[yy_current_state] ) { + yyg->yy_last_accepting_state = yy_current_state; + yyg->yy_last_accepting_cpos = yy_cp; + } + 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 >= 126 ) + 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 == 125); + + return yy_is_jam ? 0 : yy_current_state; +} + +/* %if-c-only */ + +static void yyunput (int c, register char * yy_bp , yyscan_t yyscanner) +/* %endif */ +/* %if-c++-only */ +/* %endif */ +{ + register char *yy_cp; + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + + yy_cp = yyg->yy_c_buf_p; + + /* undo effects of setting up yytext */ + *yy_cp = yyg->yy_hold_char; + + if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 ) { + /* need to shift things up to make room */ + /* +2 for EOB chars. */ + register yy_size_t number_to_move = yyg->yy_n_chars + 2; + register char *dest = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[ + YY_CURRENT_BUFFER_LVALUE->yy_buf_size + 2]; + register char *source = + &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]; + + while ( source > YY_CURRENT_BUFFER_LVALUE->yy_ch_buf ) + *--dest = *--source; + + yy_cp += (int) (dest - source); + yy_bp += (int) (dest - source); + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = + yyg->yy_n_chars = YY_CURRENT_BUFFER_LVALUE->yy_buf_size; + + if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 ) + YY_FATAL_ERROR( "flex scanner push-back overflow" ); + } + + *--yy_cp = (char) c; + + /* %% [18.0] update yylineno here */ + + if ( c == '\n' ) { + --yylineno; + } + + yyg->yytext_ptr = yy_bp; + yyg->yy_hold_char = *yy_cp; + yyg->yy_c_buf_p = yy_cp; +} +/* %if-c-only */ + +/* %endif */ + +/* %if-c-only */ +#ifndef YY_NO_INPUT +#ifdef __cplusplus +static int yyinput (yyscan_t yyscanner) +#else +static int input (yyscan_t yyscanner) +#endif + +/* %endif */ +/* %if-c++-only */ +/* %endif */ +{ + int c; + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + + *yyg->yy_c_buf_p = yyg->yy_hold_char; + + if ( *yyg->yy_c_buf_p == YY_END_OF_BUFFER_CHAR ) { + /* yy_c_buf_p now points to the character we want to return. + * If this occurs *before* the EOB characters, then it's a + * valid NUL; if not, then we've hit the end of the buffer. + */ + if ( yyg->yy_c_buf_p < &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars] ) + /* This was really a NUL. */ + *yyg->yy_c_buf_p = '\0'; + + else { + /* need more input */ + yy_size_t offset = yyg->yy_c_buf_p - yyg->yytext_ptr; + ++yyg->yy_c_buf_p; + + switch ( yy_get_next_buffer( yyscanner ) ) { + case EOB_ACT_LAST_MATCH: + /* This happens because yy_g_n_b() + * sees that we've accumulated a + * token and flags that we need to + * try matching the token before + * proceeding. But for input(), + * there's no matching to consider. + * So convert the EOB_ACT_LAST_MATCH + * to EOB_ACT_END_OF_FILE. + */ + + /* Reset buffer status. */ + promela_restart(yyin ,yyscanner); + + /*FALLTHROUGH*/ + + case EOB_ACT_END_OF_FILE: { + if ( promela_wrap(yyscanner ) ) + return 0; + + if ( ! yyg->yy_did_buffer_switch_on_eof ) + YY_NEW_FILE; +#ifdef __cplusplus + return yyinput(yyscanner); +#else + return input(yyscanner); +#endif + } + + case EOB_ACT_CONTINUE_SCAN: + yyg->yy_c_buf_p = yyg->yytext_ptr + offset; + break; + } + } + } + + c = *(unsigned char *) yyg->yy_c_buf_p; /* cast for 8-bit char's */ + *yyg->yy_c_buf_p = '\0'; /* preserve yytext */ + yyg->yy_hold_char = *++yyg->yy_c_buf_p; + + /* %% [19.0] update BOL and yylineno */ + if ( c == '\n' ) + + do { + yylineno++; + yycolumn=0; + } while(0) + ; + + return c; +} +/* %if-c-only */ +#endif /* ifndef YY_NO_INPUT */ +/* %endif */ + +/** Immediately switch to a different input stream. + * @param input_file A readable stream. + * @param yyscanner The scanner object. + * @note This function does not reset the start condition to @c INITIAL . + */ +/* %if-c-only */ +void promela_restart (FILE * input_file , yyscan_t yyscanner) +/* %endif */ +/* %if-c++-only */ +/* %endif */ +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + + if ( ! YY_CURRENT_BUFFER ) { + promela_ensure_buffer_stack (yyscanner); + YY_CURRENT_BUFFER_LVALUE = + promela__create_buffer(yyin,YY_BUF_SIZE ,yyscanner); + } + + promela__init_buffer(YY_CURRENT_BUFFER,input_file ,yyscanner); + promela__load_buffer_state(yyscanner ); +} + +/** Switch to a different input buffer. + * @param new_buffer The new input buffer. + * @param yyscanner The scanner object. + */ +/* %if-c-only */ +void promela__switch_to_buffer (YY_BUFFER_STATE new_buffer , yyscan_t yyscanner) +/* %endif */ +/* %if-c++-only */ +/* %endif */ +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + + /* TODO. We should be able to replace this entire function body + * with + * promela_pop_buffer_state(); + * promela_push_buffer_state(new_buffer); + */ + promela_ensure_buffer_stack (yyscanner); + if ( YY_CURRENT_BUFFER == new_buffer ) + return; + + if ( YY_CURRENT_BUFFER ) { + /* Flush out information for old buffer. */ + *yyg->yy_c_buf_p = yyg->yy_hold_char; + YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = yyg->yy_c_buf_p; + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars; + } + + YY_CURRENT_BUFFER_LVALUE = new_buffer; + promela__load_buffer_state(yyscanner ); + + /* We don't actually know whether we did this switch during + * EOF (promela_wrap()) processing, but the only time this flag + * is looked at is after promela_wrap() is called, so it's safe + * to go ahead and always set it. + */ + yyg->yy_did_buffer_switch_on_eof = 1; +} + +/* %if-c-only */ +static void promela__load_buffer_state (yyscan_t yyscanner) +/* %endif */ +/* %if-c++-only */ +/* %endif */ +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + yyg->yy_n_chars = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; + yyg->yytext_ptr = yyg->yy_c_buf_p = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos; + yyin = YY_CURRENT_BUFFER_LVALUE->yy_input_file; + yyg->yy_hold_char = *yyg->yy_c_buf_p; +} + +/** Allocate and initialize an input buffer state. + * @param file A readable stream. + * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE. + * @param yyscanner The scanner object. + * @return the allocated buffer state. + */ +/* %if-c-only */ +YY_BUFFER_STATE promela__create_buffer (FILE * file, int size , yyscan_t yyscanner) +/* %endif */ +/* %if-c++-only */ +/* %endif */ +{ + YY_BUFFER_STATE b; + + b = (YY_BUFFER_STATE) promela_alloc(sizeof( struct yy_buffer_state ) ,yyscanner ); + if ( ! b ) + YY_FATAL_ERROR( "out of dynamic memory in promela__create_buffer()" ); + + b->yy_buf_size = size; + + /* yy_ch_buf has to be 2 characters longer than the size given because + * we need to put in 2 end-of-buffer characters. + */ + b->yy_ch_buf = (char *) promela_alloc(b->yy_buf_size + 2 ,yyscanner ); + if ( ! b->yy_ch_buf ) + YY_FATAL_ERROR( "out of dynamic memory in promela__create_buffer()" ); + + b->yy_is_our_buffer = 1; + + promela__init_buffer(b,file ,yyscanner); + + return b; +} + +/** Destroy the buffer. + * @param b a buffer created with promela__create_buffer() + * @param yyscanner The scanner object. + */ +/* %if-c-only */ +void promela__delete_buffer (YY_BUFFER_STATE b , yyscan_t yyscanner) +/* %endif */ +/* %if-c++-only */ +/* %endif */ +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + + if ( ! b ) + return; + + if ( b == YY_CURRENT_BUFFER ) /* Not sure if we should pop here. */ + YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0; + + if ( b->yy_is_our_buffer ) + promela_free((void *) b->yy_ch_buf ,yyscanner ); + + promela_free((void *) b ,yyscanner ); +} + +/* %if-c-only */ + +/* %endif */ + +/* %if-c++-only */ +/* %endif */ + +/* Initializes or reinitializes a buffer. + * This function is sometimes called more than once on the same buffer, + * such as during a promela_restart() or at EOF. + */ +/* %if-c-only */ +static void promela__init_buffer (YY_BUFFER_STATE b, FILE * file , yyscan_t yyscanner) +/* %endif */ +/* %if-c++-only */ +/* %endif */ + +{ + int oerrno = errno; + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + + promela__flush_buffer(b ,yyscanner); + + b->yy_input_file = file; + b->yy_fill_buffer = 1; + + /* If b is the current buffer, then promela__init_buffer was _probably_ + * called from promela_restart() or through yy_get_next_buffer. + * In that case, we don't want to reset the lineno or column. + */ + if (b != YY_CURRENT_BUFFER) { + b->yy_bs_lineno = 1; + b->yy_bs_column = 0; + } + + /* %if-c-only */ + + b->yy_is_interactive = 0; + + /* %endif */ + /* %if-c++-only */ + /* %endif */ + errno = oerrno; +} + +/** Discard all buffered characters. On the next scan, YY_INPUT will be called. + * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER. + * @param yyscanner The scanner object. + */ +/* %if-c-only */ +void promela__flush_buffer (YY_BUFFER_STATE b , yyscan_t yyscanner) +/* %endif */ +/* %if-c++-only */ +/* %endif */ +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + if ( ! b ) + return; + + b->yy_n_chars = 0; + + /* We always need two end-of-buffer characters. The first causes + * a transition to the end-of-buffer state. The second causes + * a jam in that state. + */ + b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR; + b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR; + + b->yy_buf_pos = &b->yy_ch_buf[0]; + + b->yy_at_bol = 1; + b->yy_buffer_status = YY_BUFFER_NEW; + + if ( b == YY_CURRENT_BUFFER ) + promela__load_buffer_state(yyscanner ); +} + +/* %if-c-or-c++ */ +/** Pushes the new state onto the stack. The new state becomes + * the current state. This function will allocate the stack + * if necessary. + * @param new_buffer The new state. + * @param yyscanner The scanner object. + */ +/* %if-c-only */ +void promela_push_buffer_state (YY_BUFFER_STATE new_buffer , yyscan_t yyscanner) +/* %endif */ +/* %if-c++-only */ +/* %endif */ +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + if (new_buffer == NULL) + return; + + promela_ensure_buffer_stack(yyscanner); + + /* This block is copied from promela__switch_to_buffer. */ + if ( YY_CURRENT_BUFFER ) { + /* Flush out information for old buffer. */ + *yyg->yy_c_buf_p = yyg->yy_hold_char; + YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = yyg->yy_c_buf_p; + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars; + } + + /* Only push if top exists. Otherwise, replace top. */ + if (YY_CURRENT_BUFFER) + yyg->yy_buffer_stack_top++; + YY_CURRENT_BUFFER_LVALUE = new_buffer; + + /* copied from promela__switch_to_buffer. */ + promela__load_buffer_state(yyscanner ); + yyg->yy_did_buffer_switch_on_eof = 1; +} +/* %endif */ + +/* %if-c-or-c++ */ +/** Removes and deletes the top of the stack, if present. + * The next element becomes the new top. + * @param yyscanner The scanner object. + */ +/* %if-c-only */ +void promela_pop_buffer_state (yyscan_t yyscanner) +/* %endif */ +/* %if-c++-only */ +/* %endif */ +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + if (!YY_CURRENT_BUFFER) + return; + + promela__delete_buffer(YY_CURRENT_BUFFER ,yyscanner); + YY_CURRENT_BUFFER_LVALUE = NULL; + if (yyg->yy_buffer_stack_top > 0) + --yyg->yy_buffer_stack_top; + + if (YY_CURRENT_BUFFER) { + promela__load_buffer_state(yyscanner ); + yyg->yy_did_buffer_switch_on_eof = 1; + } +} +/* %endif */ + +/* %if-c-or-c++ */ +/* Allocates the stack if it does not exist. + * Guarantees space for at least one push. + */ +/* %if-c-only */ +static void promela_ensure_buffer_stack (yyscan_t yyscanner) +/* %endif */ +/* %if-c++-only */ +/* %endif */ +{ + yy_size_t num_to_alloc; + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + + if (!yyg->yy_buffer_stack) { + + /* First allocation is just for 2 elements, since we don't know if this + * scanner will even need a stack. We use 2 instead of 1 to avoid an + * immediate realloc on the next call. + */ + num_to_alloc = 1; + yyg->yy_buffer_stack = (struct yy_buffer_state**)promela_alloc + (num_to_alloc * sizeof(struct yy_buffer_state*) + , yyscanner); + if ( ! yyg->yy_buffer_stack ) + YY_FATAL_ERROR( "out of dynamic memory in promela_ensure_buffer_stack()" ); + + memset(yyg->yy_buffer_stack, 0, num_to_alloc * sizeof(struct yy_buffer_state*)); + + yyg->yy_buffer_stack_max = num_to_alloc; + yyg->yy_buffer_stack_top = 0; + return; + } + + if (yyg->yy_buffer_stack_top >= (yyg->yy_buffer_stack_max) - 1) { + + /* Increase the buffer to prepare for a possible push. */ + int grow_size = 8 /* arbitrary grow size */; + + num_to_alloc = yyg->yy_buffer_stack_max + grow_size; + yyg->yy_buffer_stack = (struct yy_buffer_state**)promela_realloc + (yyg->yy_buffer_stack, + num_to_alloc * sizeof(struct yy_buffer_state*) + , yyscanner); + if ( ! yyg->yy_buffer_stack ) + YY_FATAL_ERROR( "out of dynamic memory in promela_ensure_buffer_stack()" ); + + /* zero only the new slots.*/ + memset(yyg->yy_buffer_stack + yyg->yy_buffer_stack_max, 0, grow_size * sizeof(struct yy_buffer_state*)); + yyg->yy_buffer_stack_max = num_to_alloc; + } +} +/* %endif */ + +/* %if-c-only */ +/** Setup the input buffer state to scan directly from a user-specified character buffer. + * @param base the character buffer + * @param size the size in bytes of the character buffer + * @param yyscanner The scanner object. + * @return the newly allocated buffer state object. + */ +YY_BUFFER_STATE promela__scan_buffer (char * base, yy_size_t size , yyscan_t yyscanner) { + YY_BUFFER_STATE b; + + if ( size < 2 || + base[size-2] != YY_END_OF_BUFFER_CHAR || + base[size-1] != YY_END_OF_BUFFER_CHAR ) + /* They forgot to leave room for the EOB's. */ + return 0; + + b = (YY_BUFFER_STATE) promela_alloc(sizeof( struct yy_buffer_state ) ,yyscanner ); + if ( ! b ) + YY_FATAL_ERROR( "out of dynamic memory in promela__scan_buffer()" ); + + b->yy_buf_size = size - 2; /* "- 2" to take care of EOB's */ + b->yy_buf_pos = b->yy_ch_buf = base; + b->yy_is_our_buffer = 0; + b->yy_input_file = 0; + b->yy_n_chars = b->yy_buf_size; + b->yy_is_interactive = 0; + b->yy_at_bol = 1; + b->yy_fill_buffer = 0; + b->yy_buffer_status = YY_BUFFER_NEW; + + promela__switch_to_buffer(b ,yyscanner ); + + return b; +} +/* %endif */ + +/* %if-c-only */ +/** Setup the input buffer state to scan a string. The next call to promela_lex() will + * scan from a @e copy of @a str. + * @param yystr a NUL-terminated string to scan + * @param yyscanner The scanner object. + * @return the newly allocated buffer state object. + * @note If you want to scan bytes that may contain NUL values, then use + * promela__scan_bytes() instead. + */ +YY_BUFFER_STATE promela__scan_string (yyconst char * yystr , yyscan_t yyscanner) { + + return promela__scan_bytes(yystr,strlen(yystr) ,yyscanner); +} +/* %endif */ + +/* %if-c-only */ +/** Setup the input buffer state to scan the given bytes. The next call to promela_lex() will + * scan from a @e copy of @a bytes. + * @param bytes the byte buffer to scan + * @param len the number of bytes in the buffer pointed to by @a bytes. + * @param yyscanner The scanner object. + * @return the newly allocated buffer state object. + */ +YY_BUFFER_STATE promela__scan_bytes (yyconst char * yybytes, yy_size_t _yybytes_len , yyscan_t yyscanner) { + YY_BUFFER_STATE b; + char *buf; + yy_size_t n, i; + + /* Get memory for full buffer, including space for trailing EOB's. */ + n = _yybytes_len + 2; + buf = (char *) promela_alloc(n ,yyscanner ); + if ( ! buf ) + YY_FATAL_ERROR( "out of dynamic memory in promela__scan_bytes()" ); + + for ( i = 0; i < _yybytes_len; ++i ) + buf[i] = yybytes[i]; + + buf[_yybytes_len] = buf[_yybytes_len+1] = YY_END_OF_BUFFER_CHAR; + + b = promela__scan_buffer(buf,n ,yyscanner); + if ( ! b ) + YY_FATAL_ERROR( "bad buffer in promela__scan_bytes()" ); + + /* It's okay to grow etc. this buffer, and we should throw it + * away when we're done. + */ + b->yy_is_our_buffer = 1; + + return b; +} +/* %endif */ + +#ifndef YY_EXIT_FAILURE +#define YY_EXIT_FAILURE 2 +#endif + +/* %if-c-only */ +static void yy_fatal_error (yyconst char* msg , yyscan_t yyscanner) { + (void) fprintf( stderr, "%s\n", msg ); + exit( YY_EXIT_FAILURE ); +} +/* %endif */ +/* %if-c++-only */ +/* %endif */ + +/* Redefine yyless() so it works in section 3 code. */ + +#undef yyless +#define yyless(n) \ + do \ + { \ + /* Undo effects of setting up yytext. */ \ + int yyless_macro_arg = (n); \ + YY_LESS_LINENO(yyless_macro_arg);\ + yytext[yyleng] = yyg->yy_hold_char; \ + yyg->yy_c_buf_p = yytext + yyless_macro_arg; \ + yyg->yy_hold_char = *yyg->yy_c_buf_p; \ + *yyg->yy_c_buf_p = '\0'; \ + yyleng = yyless_macro_arg; \ + } \ + while ( 0 ) + +/* Accessor methods (get/set functions) to struct members. */ + +/* %if-c-only */ +/* %if-reentrant */ + +/** Get the user-defined data for this scanner. + * @param yyscanner The scanner object. + */ +YY_EXTRA_TYPE promela_get_extra (yyscan_t yyscanner) { + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + return yyextra; +} + +/* %endif */ + +/** Get the current line number. + * @param yyscanner The scanner object. + */ +int promela_get_lineno (yyscan_t yyscanner) { + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + + if (! YY_CURRENT_BUFFER) + return 0; + + return yylineno; +} + +/** Get the current column number. + * @param yyscanner The scanner object. + */ +int promela_get_column (yyscan_t yyscanner) { + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + + if (! YY_CURRENT_BUFFER) + return 0; + + return yycolumn; +} + +/** Get the input stream. + * @param yyscanner The scanner object. + */ +FILE *promela_get_in (yyscan_t yyscanner) { + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + return yyin; +} + +/** Get the output stream. + * @param yyscanner The scanner object. + */ +FILE *promela_get_out (yyscan_t yyscanner) { + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + return yyout; +} + +/** Get the length of the current token. + * @param yyscanner The scanner object. + */ +yy_size_t promela_get_leng (yyscan_t yyscanner) { + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + return yyleng; +} + +/** Get the current token. + * @param yyscanner The scanner object. + */ + +char *promela_get_text (yyscan_t yyscanner) { + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + return yytext; +} + +/* %if-reentrant */ + +/** Set the user-defined data. This data is never touched by the scanner. + * @param user_defined The data to be associated with this scanner. + * @param yyscanner The scanner object. + */ +void promela_set_extra (YY_EXTRA_TYPE user_defined , yyscan_t yyscanner) { + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + yyextra = user_defined ; +} + +/* %endif */ + +/** Set the current line number. + * @param line_number + * @param yyscanner The scanner object. + */ +void promela_set_lineno (int line_number , yyscan_t yyscanner) { + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + + /* lineno is only valid if an input buffer exists. */ + if (! YY_CURRENT_BUFFER ) + yy_fatal_error( "promela_set_lineno called with no buffer" , yyscanner); + + yylineno = line_number; +} + +/** Set the current column. + * @param line_number + * @param yyscanner The scanner object. + */ +void promela_set_column (int column_no , yyscan_t yyscanner) { + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + + /* column is only valid if an input buffer exists. */ + if (! YY_CURRENT_BUFFER ) + yy_fatal_error( "promela_set_column called with no buffer" , yyscanner); + + yycolumn = column_no; +} + +/** Set the input stream. This does not discard the current + * input buffer. + * @param in_str A readable stream. + * @param yyscanner The scanner object. + * @see promela__switch_to_buffer + */ +void promela_set_in (FILE * in_str , yyscan_t yyscanner) { + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + yyin = in_str ; +} + +void promela_set_out (FILE * out_str , yyscan_t yyscanner) { + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + yyout = out_str ; +} + +int promela_get_debug (yyscan_t yyscanner) { + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + return yy_flex_debug; +} + +void promela_set_debug (int bdebug , yyscan_t yyscanner) { + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + yy_flex_debug = bdebug ; +} + +/* %endif */ + +/* %if-reentrant */ +/* Accessor methods for yylval and yylloc */ + +/* %if-bison-bridge */ + +YYSTYPE * promela_get_lval (yyscan_t yyscanner) { + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + return yylval; +} + +void promela_set_lval (YYSTYPE * yylval_param , yyscan_t yyscanner) { + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + yylval = yylval_param; +} + +YYLTYPE *promela_get_lloc (yyscan_t yyscanner) { + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + return yylloc; +} + +void promela_set_lloc (YYLTYPE * yylloc_param , yyscan_t yyscanner) { + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + yylloc = yylloc_param; +} + +/* %endif */ + +/* User-visible API */ + +/* promela_lex_init is special because it creates the scanner itself, so it is + * the ONLY reentrant function that doesn't take the scanner as the last argument. + * That's why we explicitly handle the declaration, instead of using our macros. + */ + +int promela_lex_init(yyscan_t* ptr_yy_globals) + +{ + if (ptr_yy_globals == NULL) { + errno = EINVAL; + return 1; + } + + *ptr_yy_globals = (yyscan_t) promela_alloc ( sizeof( struct yyguts_t ), NULL ); + + if (*ptr_yy_globals == NULL) { + errno = ENOMEM; + return 1; + } + + /* By setting to 0xAA, we expose bugs in yy_init_globals. Leave at 0x00 for releases. */ + memset(*ptr_yy_globals,0x00,sizeof(struct yyguts_t)); + + return yy_init_globals ( *ptr_yy_globals ); +} + +/* promela_lex_init_extra has the same functionality as promela_lex_init, but follows the + * convention of taking the scanner as the last argument. Note however, that + * this is a *pointer* to a scanner, as it will be allocated by this call (and + * is the reason, too, why this function also must handle its own declaration). + * The user defined value in the first argument will be available to promela_alloc in + * the yyextra field. + */ + +int promela_lex_init_extra(YY_EXTRA_TYPE yy_user_defined,yyscan_t* ptr_yy_globals ) + +{ + struct yyguts_t dummy_yyguts; + + promela_set_extra (yy_user_defined, &dummy_yyguts); + + if (ptr_yy_globals == NULL) { + errno = EINVAL; + return 1; + } + + *ptr_yy_globals = (yyscan_t) promela_alloc ( sizeof( struct yyguts_t ), &dummy_yyguts ); + + if (*ptr_yy_globals == NULL) { + errno = ENOMEM; + return 1; + } + + /* By setting to 0xAA, we expose bugs in + yy_init_globals. Leave at 0x00 for releases. */ + memset(*ptr_yy_globals,0x00,sizeof(struct yyguts_t)); + + promela_set_extra (yy_user_defined, *ptr_yy_globals); + + return yy_init_globals ( *ptr_yy_globals ); +} + +/* %endif if-c-only */ + +/* %if-c-only */ +static int yy_init_globals (yyscan_t yyscanner) { + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + /* Initialization is the same as for the non-reentrant scanner. + * This function is called from promela_lex_destroy(), so don't allocate here. + */ + + yyg->yy_buffer_stack = 0; + yyg->yy_buffer_stack_top = 0; + yyg->yy_buffer_stack_max = 0; + yyg->yy_c_buf_p = (char *) 0; + yyg->yy_init = 0; + yyg->yy_start = 0; + + yyg->yy_start_stack_ptr = 0; + yyg->yy_start_stack_depth = 0; + yyg->yy_start_stack = NULL; + + /* Defined in main.c */ +#ifdef YY_STDINIT + yyin = stdin; + yyout = stdout; +#else + yyin = (FILE *) 0; + yyout = (FILE *) 0; +#endif + + /* For future reference: Set errno on error, since we are called by + * promela_lex_init() + */ + return 0; +} +/* %endif */ + +/* %if-c-only SNIP! this currently causes conflicts with the c++ scanner */ +/* promela_lex_destroy is for both reentrant and non-reentrant scanners. */ +int promela_lex_destroy (yyscan_t yyscanner) { + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + + /* Pop the buffer stack, destroying each element. */ + while(YY_CURRENT_BUFFER) { + promela__delete_buffer(YY_CURRENT_BUFFER ,yyscanner ); + YY_CURRENT_BUFFER_LVALUE = NULL; + promela_pop_buffer_state(yyscanner); + } + + /* Destroy the stack itself. */ + promela_free(yyg->yy_buffer_stack ,yyscanner); + yyg->yy_buffer_stack = NULL; + + /* Destroy the start condition stack. */ + promela_free(yyg->yy_start_stack ,yyscanner ); + yyg->yy_start_stack = NULL; + + /* Reset the globals. This is important in a non-reentrant scanner so the next time + * promela_lex() is called, initialization will occur. */ + yy_init_globals( yyscanner); + + /* %if-reentrant */ + /* Destroy the main struct (reentrant only). */ + promela_free ( yyscanner , yyscanner ); + yyscanner = NULL; + /* %endif */ + return 0; +} +/* %endif */ + +/* + * Internal utility routines. + */ + +#ifndef yytext_ptr +static void yy_flex_strncpy (char* s1, yyconst char * s2, int n , yyscan_t yyscanner) { + register int i; + for ( i = 0; i < n; ++i ) + s1[i] = s2[i]; +} +#endif + +#ifdef YY_NEED_STRLEN +static int yy_flex_strlen (yyconst char * s , yyscan_t yyscanner) { + register int n; + for ( n = 0; s[n]; ++n ) + ; + + return n; +} +#endif + +void *promela_alloc (yy_size_t size , yyscan_t yyscanner) { + return (void *) malloc( size ); +} + +void *promela_realloc (void * ptr, yy_size_t size , yyscan_t yyscanner) { + /* The cast to (char *) in the following accommodates both + * implementations that use char* generic pointers, and those + * that use void* generic pointers. It works with the latter + * because both ANSI C and C++ allow castless assignment from + * any pointer type to void*, and deal with argument conversions + * as though doing an assignment. + */ + return (void *) realloc( (char *) ptr, size ); +} + +void promela_free (void * ptr , yyscan_t yyscanner) { + free( (char *) ptr ); /* see promela_realloc() for (char *) cast */ +} + +/* %if-tables-serialization definitions */ +/* %define-yytables The name for this specific scanner's tables. */ +#define YYTABLES_NAME "yytables" +/* %endif */ + +/* %ok-for-header */ + +#line 118 "promela.l" diff --git a/src/uscxml/plugins/datamodel/promela/parser/promela.tab.cpp b/src/uscxml/plugins/datamodel/promela/parser/promela.tab.cpp new file mode 100644 index 0000000..098c890 --- /dev/null +++ b/src/uscxml/plugins/datamodel/promela/parser/promela.tab.cpp @@ -0,0 +1,2634 @@ +/* A Bison parser, made by GNU Bison 2.7.12-4996. */ + +/* Bison implementation for Yacc-like parsers in C + + Copyright (C) 1984, 1989-1990, 2000-2013 Free Software Foundation, Inc. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +/* As a special exception, you may create a larger work that contains + part or all of the Bison parser skeleton and distribute that work + under terms of your choice, so long as that work isn't itself a + parser generator using the skeleton or a modified version thereof + as a parser skeleton. Alternatively, if you modify or redistribute + the parser skeleton itself, you may (at your option) remove this + special exception, which will cause the skeleton and the resulting + Bison output files to be licensed under the GNU General Public + License without this special exception. + + This special exception was added by the Free Software Foundation in + version 2.2 of Bison. */ + +/* C LALR(1) parser skeleton written by Richard Stallman, by + simplifying the original so-called "semantic" parser. */ + +/* All symbols defined below should begin with yy or YY, to avoid + infringing on user name space. This should be done even for local + variables, as they might otherwise be expanded by user macros. + There are some unavoidable exceptions within include files to + define necessary library symbols; they are noted "INFRINGES ON + USER NAME SPACE" below. */ + +/* Identify Bison output. */ +#define YYBISON 1 + +/* Bison version. */ +#define YYBISON_VERSION "2.7.12-4996" + +/* Skeleton name. */ +#define YYSKELETON_NAME "yacc.c" + +/* Pure parsers. */ +#define YYPURE 1 + +/* Push parsers. */ +#define YYPUSH 0 + +/* Pull parsers. */ +#define YYPULL 1 + +/* Substitute the type names. */ +#define YYSTYPE PROMELA_STYPE +#define YYLTYPE PROMELA_LTYPE +/* Substitute the variable and function names. */ +#define yyparse promela_parse +#define yylex promela_lex +#define yyerror promela_error +#define yylval promela_lval +#define yychar promela_char +#define yydebug promela_debug +#define yynerrs promela_nerrs +#define yylloc promela_lloc + +/* Copy the first part of user declarations. */ +/* Line 371 of yacc.c */ +#line 14 "promela.ypp" + +#include "../PromelaParser.h" +#include "promela.tab.hpp" +#include +#include + +#define YYMAXDEPTH 20000 // default is 10000 +#define YYDEBUG 1 +#define YYERROR_VERBOSE 1 + +extern int promela_lex (PROMELA_STYPE* yylval_param, PROMELA_LTYPE* yylloc_param, void* yyscanner); + +using namespace uscxml; + +/* Line 371 of yacc.c */ +#line 93 "promela.tab.cpp" + +# ifndef YY_NULL +# if defined __cplusplus && 201103L <= __cplusplus +# define YY_NULL nullptr +# else +# define YY_NULL 0 +# endif +# endif + +/* Enabling verbose error messages. */ +#ifdef YYERROR_VERBOSE +# undef YYERROR_VERBOSE +# define YYERROR_VERBOSE 1 +#else +# define YYERROR_VERBOSE 1 +#endif + +/* In a future release of Bison, this section will be replaced + by #include "promela.tab.hpp". */ +#ifndef YY_PROMELA_PROMELA_TAB_HPP_INCLUDED +# define YY_PROMELA_PROMELA_TAB_HPP_INCLUDED +/* Enabling traces. */ +#ifndef PROMELA_DEBUG +# if defined YYDEBUG +# if YYDEBUG +# define PROMELA_DEBUG 1 +# else +# define PROMELA_DEBUG 0 +# endif +# else /* ! defined YYDEBUG */ +# define PROMELA_DEBUG 1 +# endif /* ! defined YYDEBUG */ +#endif /* ! defined PROMELA_DEBUG */ +#if PROMELA_DEBUG +extern int promela_debug; +#endif + +/* Tokens. */ +#ifndef PROMELA_TOKENTYPE +# define PROMELA_TOKENTYPE +/* Put the tokens into the symbol table, so that GDB and other debuggers + know about them. */ +enum promela_tokentype { + PML_VAR_ARRAY = 258, + PML_VARLIST = 259, + PML_DECL = 260, + PML_DECLLIST = 261, + PML_STMNT = 262, + PML_COLON = 263, + PML_EXPR = 264, + PML_NAMELIST = 265, + PML_ASSERT = 266, + PML_PRINT = 267, + PML_PRINTM = 268, + PML_LEN = 269, + PML_STRING = 270, + PML_TYPEDEF = 271, + PML_MTYPE = 272, + PML_INLINE = 273, + PML_RETURN = 274, + PML_LABEL = 275, + PML_OF = 276, + PML_GOTO = 277, + PML_BREAK = 278, + PML_ELSE = 279, + PML_SEMI = 280, + PML_ARROW = 281, + PML_IF = 282, + PML_FI = 283, + PML_DO = 284, + PML_OD = 285, + PML_FOR = 286, + PML_SELECT = 287, + PML_IN = 288, + PML_SEP = 289, + PML_DOTDOT = 290, + PML_HIDDEN = 291, + PML_SHOW = 292, + PML_ISLOCAL = 293, + PML_CONST = 294, + PML_TYPE = 295, + PML_XU = 296, + PML_NAME = 297, + PML_UNAME = 298, + PML_PNAME = 299, + PML_INAME = 300, + PML_CLAIM = 301, + PML_TRACE = 302, + PML_INIT = 303, + PML_LTL = 304, + PML_COMMA = 305, + PML_ASGN = 306, + PML_AND = 307, + PML_OR = 308, + PML_BITAND = 309, + PML_BITXOR = 310, + PML_BITOR = 311, + PML_NE = 312, + PML_EQ = 313, + PML_LE = 314, + PML_GE = 315, + PML_LT = 316, + PML_GT = 317, + PML_RSHIFT = 318, + PML_LSHIFT = 319, + PML_MINUS = 320, + PML_PLUS = 321, + PML_MODULO = 322, + PML_DIVIDE = 323, + PML_TIMES = 324, + PML_DECR = 325, + PML_INCR = 326, + PML_COMPL = 327, + PML_NEG = 328, + PML_CMPND = 329, + PML_DOT = 330 +}; +#endif + + +#if ! defined PROMELA_STYPE && ! defined PROMELA_STYPE_IS_DECLARED +typedef union PROMELA_STYPE { + /* Line 387 of yacc.c */ +#line 39 "promela.ypp" + + uscxml::PromelaParserNode* node; + char* value; + + + /* Line 387 of yacc.c */ +#line 225 "promela.tab.cpp" +} PROMELA_STYPE; +# define PROMELA_STYPE_IS_TRIVIAL 1 +# define promela_stype PROMELA_STYPE /* obsolescent; will be withdrawn */ +# define PROMELA_STYPE_IS_DECLARED 1 +#endif + +#if ! defined PROMELA_LTYPE && ! defined PROMELA_LTYPE_IS_DECLARED +typedef struct PROMELA_LTYPE { + int first_line; + int first_column; + int last_line; + int last_column; +} PROMELA_LTYPE; +# define promela_ltype PROMELA_LTYPE /* obsolescent; will be withdrawn */ +# define PROMELA_LTYPE_IS_DECLARED 1 +# define PROMELA_LTYPE_IS_TRIVIAL 1 +#endif + + +#ifdef YYPARSE_PARAM +#if defined __STDC__ || defined __cplusplus +int promela_parse (void *YYPARSE_PARAM); +#else +int promela_parse (); +#endif +#else /* ! YYPARSE_PARAM */ +#if defined __STDC__ || defined __cplusplus +int promela_parse (uscxml::PromelaParser* ctx, void * scanner); +#else +int promela_parse (); +#endif +#endif /* ! YYPARSE_PARAM */ + +#endif /* !YY_PROMELA_PROMELA_TAB_HPP_INCLUDED */ + +/* Copy the second part of user declarations. */ + +/* Line 390 of yacc.c */ +#line 265 "promela.tab.cpp" + +#ifdef short +# undef short +#endif + +#ifdef YYTYPE_UINT8 +typedef YYTYPE_UINT8 yytype_uint8; +#else +typedef unsigned char yytype_uint8; +#endif + +#ifdef YYTYPE_INT8 +typedef YYTYPE_INT8 yytype_int8; +#elif (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +typedef signed char yytype_int8; +#else +typedef short int yytype_int8; +#endif + +#ifdef YYTYPE_UINT16 +typedef YYTYPE_UINT16 yytype_uint16; +#else +typedef unsigned short int yytype_uint16; +#endif + +#ifdef YYTYPE_INT16 +typedef YYTYPE_INT16 yytype_int16; +#else +typedef short int yytype_int16; +#endif + +#ifndef YYSIZE_T +# ifdef __SIZE_TYPE__ +# define YYSIZE_T __SIZE_TYPE__ +# elif defined size_t +# define YYSIZE_T size_t +# elif ! defined YYSIZE_T && (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +# include /* INFRINGES ON USER NAME SPACE */ +# define YYSIZE_T size_t +# else +# define YYSIZE_T unsigned int +# endif +#endif + +#define YYSIZE_MAXIMUM ((YYSIZE_T) -1) + +#ifndef YY_ +# if defined YYENABLE_NLS && YYENABLE_NLS +# if ENABLE_NLS +# include /* INFRINGES ON USER NAME SPACE */ +# define YY_(Msgid) dgettext ("bison-runtime", Msgid) +# endif +# endif +# ifndef YY_ +# define YY_(Msgid) Msgid +# endif +#endif + +#ifndef __attribute__ +/* This feature is available in gcc versions 2.5 and later. */ +# if (! defined __GNUC__ || __GNUC__ < 2 \ + || (__GNUC__ == 2 && __GNUC_MINOR__ < 5)) +# define __attribute__(Spec) /* empty */ +# endif +#endif + +/* Suppress unused-variable warnings by "using" E. */ +#if ! defined lint || defined __GNUC__ +# define YYUSE(E) ((void) (E)) +#else +# define YYUSE(E) /* empty */ +#endif + + +/* Identity function, used to suppress warnings about constant conditions. */ +#ifndef lint +# define YYID(N) (N) +#else +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static int +YYID (int yyi) +#else +static int +YYID (yyi) +int yyi; +#endif +{ + return yyi; +} +#endif + +#if ! defined yyoverflow || YYERROR_VERBOSE + +/* The parser invokes alloca or malloc; define the necessary symbols. */ + +# ifdef YYSTACK_USE_ALLOCA +# if YYSTACK_USE_ALLOCA +# ifdef __GNUC__ +# define YYSTACK_ALLOC __builtin_alloca +# elif defined __BUILTIN_VA_ARG_INCR +# include /* INFRINGES ON USER NAME SPACE */ +# elif defined _AIX +# define YYSTACK_ALLOC __alloca +# elif defined _MSC_VER +# include /* INFRINGES ON USER NAME SPACE */ +# define alloca _alloca +# else +# define YYSTACK_ALLOC alloca +# if ! defined _ALLOCA_H && ! defined EXIT_SUCCESS && (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +# include /* INFRINGES ON USER NAME SPACE */ +/* Use EXIT_SUCCESS as a witness for stdlib.h. */ +# ifndef EXIT_SUCCESS +# define EXIT_SUCCESS 0 +# endif +# endif +# endif +# endif +# endif + +# ifdef YYSTACK_ALLOC +/* Pacify GCC's `empty if-body' warning. */ +# define YYSTACK_FREE(Ptr) do { /* empty */; } while (YYID (0)) +# ifndef YYSTACK_ALLOC_MAXIMUM +/* The OS might guarantee only one guard page at the bottom of the stack, + and a page size can be as small as 4096 bytes. So we cannot safely + invoke alloca (N) if N exceeds 4096. Use a slightly smaller number + to allow for a few compiler-allocated temporary stack slots. */ +# define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */ +# endif +# else +# define YYSTACK_ALLOC YYMALLOC +# define YYSTACK_FREE YYFREE +# ifndef YYSTACK_ALLOC_MAXIMUM +# define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM +# endif +# if (defined __cplusplus && ! defined EXIT_SUCCESS \ + && ! ((defined YYMALLOC || defined malloc) \ + && (defined YYFREE || defined free))) +# include /* INFRINGES ON USER NAME SPACE */ +# ifndef EXIT_SUCCESS +# define EXIT_SUCCESS 0 +# endif +# endif +# ifndef YYMALLOC +# define YYMALLOC malloc +# if ! defined malloc && ! defined EXIT_SUCCESS && (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */ +# endif +# endif +# ifndef YYFREE +# define YYFREE free +# if ! defined free && ! defined EXIT_SUCCESS && (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +void free (void *); /* INFRINGES ON USER NAME SPACE */ +# endif +# endif +# endif +#endif /* ! defined yyoverflow || YYERROR_VERBOSE */ + + +#if (! defined yyoverflow \ + && (! defined __cplusplus \ + || (defined PROMELA_LTYPE_IS_TRIVIAL && PROMELA_LTYPE_IS_TRIVIAL \ + && defined PROMELA_STYPE_IS_TRIVIAL && PROMELA_STYPE_IS_TRIVIAL))) + +/* A type that is properly aligned for any stack member. */ +union yyalloc { + yytype_int16 yyss_alloc; + YYSTYPE yyvs_alloc; + YYLTYPE yyls_alloc; +}; + +/* The size of the maximum gap between one aligned stack and the next. */ +# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1) + +/* The size of an array large to enough to hold all stacks, each with + N elements. */ +# define YYSTACK_BYTES(N) \ + ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE) + sizeof (YYLTYPE)) \ + + 2 * YYSTACK_GAP_MAXIMUM) + +# define YYCOPY_NEEDED 1 + +/* Relocate STACK from its old location to the new one. The + local variables YYSIZE and YYSTACKSIZE give the old and new number of + elements in the stack, and YYPTR gives the new location of the + stack. Advance YYPTR to a properly aligned location for the next + stack. */ +# define YYSTACK_RELOCATE(Stack_alloc, Stack) \ + do \ + { \ + YYSIZE_T yynewbytes; \ + YYCOPY (&yyptr->Stack_alloc, Stack, yysize); \ + Stack = &yyptr->Stack_alloc; \ + yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \ + yyptr += yynewbytes / sizeof (*yyptr); \ + } \ + while (YYID (0)) + +#endif + +#if defined YYCOPY_NEEDED && YYCOPY_NEEDED +/* Copy COUNT objects from SRC to DST. The source and destination do + not overlap. */ +# ifndef YYCOPY +# if defined __GNUC__ && 1 < __GNUC__ +# define YYCOPY(Dst, Src, Count) \ + __builtin_memcpy (Dst, Src, (Count) * sizeof (*(Src))) +# else +# define YYCOPY(Dst, Src, Count) \ + do \ + { \ + YYSIZE_T yyi; \ + for (yyi = 0; yyi < (Count); yyi++) \ + (Dst)[yyi] = (Src)[yyi]; \ + } \ + while (YYID (0)) +# endif +# endif +#endif /* !YYCOPY_NEEDED */ + +/* YYFINAL -- State number of the termination state. */ +#define YYFINAL 32 +/* YYLAST -- Last index in YYTABLE. */ +#define YYLAST 285 + +/* YYNTOKENS -- Number of terminals. */ +#define YYNTOKENS 82 +/* YYNNTS -- Number of nonterminals. */ +#define YYNNTS 21 +/* YYNRULES -- Number of rules. */ +#define YYNRULES 81 +/* YYNRULES -- Number of states. */ +#define YYNSTATES 143 + +/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */ +#define YYUNDEFTOK 2 +#define YYMAXUTOK 330 + +#define YYTRANSLATE(YYX) \ + ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) + +/* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX. */ +static const yytype_uint8 yytranslate[] = { + 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 11, 12, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 13, 2, 14, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 15, 2, 16, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, + 5, 6, 7, 8, 9, 10, 17, 18, 19, 20, + 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, + 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, + 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, + 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, 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, + 264, 266 +}; + +/* YYRHS -- A `-1'-separated list of the rules' RHS. */ +static const yytype_int8 yyrhs[] = { + 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, 101, 12, -1, 18, 11, 84, 12, -1, + 18, 11, 45, 12, -1, 17, 88, -1, 88, -1, + -1, 56, 102, -1, 88, -1, 88, 56, 102, -1 +}; + +/* YYRLINE[YYN] -- source line where rule number YYN was defined. */ +static const yytype_uint8 yyrline[] = { + 0, 85, 85, 89, 93, 99, 102, 103, 106, 121, + 122, 132, 133, 134, 135, 136, 137, 138, 139, 140, + 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, + 151, 152, 154, 155, 156, 157, 163, 164, 165, 166, + 169, 170, 171, 172, 175, 178, 179, 180, 190, 191, + 194, 195, 198, 199, 200, 203, 204, 205, 206, 207, + 208, 209, 210, 213, 214, 223, 226, 227, 228, 231, + 234, 235, 236, 237, 238, 239, 240, 241, 244, 245, + 248, 249 +}; +#endif + +#if PROMELA_DEBUG || YYERROR_VERBOSE || 1 +/* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM. + First, the terminals, then, starting at YYNTOKENS, nonterminals. */ +static const char *const yytname[] = { + "$end", "error", "$undefined", "PML_VAR_ARRAY", "PML_VARLIST", + "PML_DECL", "PML_DECLLIST", "PML_STMNT", "PML_COLON", "PML_EXPR", + "PML_NAMELIST", "'('", "')'", "'['", "']'", "'{'", "'}'", "PML_ASSERT", + "PML_PRINT", "PML_PRINTM", "PML_LEN", "PML_STRING", "PML_TYPEDEF", + "PML_MTYPE", "PML_INLINE", "PML_RETURN", "PML_LABEL", "PML_OF", + "PML_GOTO", "PML_BREAK", "PML_ELSE", "PML_SEMI", "PML_ARROW", "PML_IF", + "PML_FI", "PML_DO", "PML_OD", "PML_FOR", "PML_SELECT", "PML_IN", + "PML_SEP", "PML_DOTDOT", "PML_HIDDEN", "PML_SHOW", "PML_ISLOCAL", + "PML_CONST", "PML_TYPE", "PML_XU", "PML_NAME", "PML_UNAME", "PML_PNAME", + "PML_INAME", "PML_CLAIM", "PML_TRACE", "PML_INIT", "PML_LTL", + "PML_COMMA", "PML_ASGN", "PML_AND", "PML_OR", "PML_BITAND", "PML_BITXOR", + "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_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", "prargs", "arg", YY_NULL +}; +#endif + +# ifdef YYPRINT +/* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to + token YYLEX-NUM. */ +static const yytype_uint16 yytoknum[] = { + 0, 256, 257, 258, 259, 260, 261, 262, 263, 264, + 265, 40, 41, 91, 93, 123, 125, 266, 267, 268, + 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, + 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, + 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, + 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, 330 +}; +# endif + +/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ +static const yytype_uint8 yyr1[] = { + 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, 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, 101, + 102, 102 +}; + +/* 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, 2, 0, + 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 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, 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, 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, + 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, 0, 0, 0, 43, + 36, 67, 11, 78, 0, 0, 0, 0, 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, 36, 0, 0, 0, 0, 0, + 80, 79, 73, 0, 53, 0, 55, 0, 0, 63, + 0, 49, 51, 0, 44, 0, 56, 54, 0, 0, + 0, 0, 0, 42, 64, 65, 81, 57, 59, 58, + 62, 61, 60 +}; + +/* YYDEFGOTO[NTERM-NUM]. */ +static const yytype_int8 yydefgoto[] = { + -1, 13, 24, 15, 16, 37, 110, 18, 19, 59, + 20, 91, 92, 93, 118, 120, 21, 22, 23, 99, + 111 +}; + +/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing + STATE-NUM. */ +#define YYPACT_NINF -112 +static const yytype_int16 yypact[] = { + 14, 53, 53, 3, 13, -112, -112, -112, -112, -112, + 15, 53, 53, 26, 34, -51, -112, 138, 81, 5, + -112, -112, 58, -112, -112, 75, 160, 169, 42, 53, + -66, -112, -112, 53, -112, -112, 42, -112, 53, 53, + 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, + 53, 53, 53, 53, 53, 53, 44, -35, 51, -112, + 72, 49, -112, 46, 88, 96, 100, 93, 160, -112, + 176, 176, 189, 189, 189, 200, 200, 207, 207, 207, + 207, 120, 120, -66, -66, -112, -112, -112, 98, -3, + 102, -112, 63, 74, -112, -112, 160, -112, 53, 113, + -112, -112, -112, -112, 62, 126, -8, 167, 51, 53, + 114, -112, -112, 267, -112, -8, -112, -8, 9, -112, + 70, -112, 160, 53, -112, 4, 48, -112, -8, -8, + -8, -8, -8, -112, -112, -112, -112, -112, 48, 48, + -112, -112, -112 +}; + +/* YYPGOTO[NTERM-NUM]. */ +static const yytype_int16 yypgoto[] = { + -112, -112, 68, -112, 180, -112, 0, -112, -112, -112, + -33, -43, -112, -112, -111, -112, 223, -112, -112, -112, + 162 +}; + +/* 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 -78 +static const yytype_int16 yytable[] = { + 17, 25, 26, 115, 125, 105, 126, 53, 54, 55, + 106, 30, 31, 89, 27, 94, 137, 138, 139, 140, + 141, 142, 90, 127, 28, 1, 32, 95, 29, 67, + 36, 2, 3, 68, 4, 5, 60, 116, 70, 71, + 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, + 82, 83, 84, 85, 86, 87, 6, 7, 8, 9, + 1, 96, 10, 117, 1, 121, 2, 3, 14, 4, + 5, 113, -46, 4, 5, 128, 129, 130, 131, 132, + 128, 129, 130, 131, 132, 11, 133, 62, -46, 61, + 10, 33, 88, 12, 9, 65, 66, 10, 9, 89, + 100, 10, 98, 56, 6, 7, 8, 103, 101, 122, + 34, 35, 102, 104, 6, 7, 8, 107, 134, 108, + 11, 130, 131, 132, 11, 112, 135, 57, 12, 14, + 58, 109, 12, 38, 39, 40, 41, 42, 43, 44, + 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, + 55, 38, 39, 40, 41, 42, 43, 44, 45, 46, + 47, 48, 49, 50, 51, 52, 53, 54, 55, -77, + 123, 114, 38, 39, 40, 41, 42, 43, 44, 45, + 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, + 63, 51, 52, 53, 54, 55, 38, 39, 40, 41, + 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, + 52, 53, 54, 55, 64, 119, 69, 10, 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, 45, 46, 47, 48, 49, + 50, 51, 52, 53, 54, 55, 49, 50, 51, 52, + 53, 54, 55, 124, 97, 136 +}; + +#define yypact_value_is_default(Yystate) \ + (!!((Yystate) == (-112))) + +#define yytable_value_is_error(Yytable_value) \ + YYID (0) + +static const yytype_uint8 yycheck[] = { + 0, 1, 2, 11, 115, 8, 117, 73, 74, 75, + 13, 11, 12, 48, 11, 58, 12, 128, 129, 130, + 131, 132, 57, 14, 11, 11, 0, 60, 13, 29, + 81, 17, 18, 33, 20, 21, 31, 45, 38, 39, + 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, + 50, 51, 52, 53, 54, 55, 42, 43, 44, 45, + 11, 61, 48, 71, 11, 108, 17, 18, 0, 20, + 21, 104, 0, 20, 21, 71, 72, 73, 74, 75, + 71, 72, 73, 74, 75, 71, 16, 12, 16, 31, + 48, 57, 48, 79, 45, 27, 28, 48, 45, 48, + 12, 48, 56, 22, 42, 43, 44, 14, 12, 109, + 76, 77, 12, 15, 42, 43, 44, 15, 48, 56, + 71, 73, 74, 75, 71, 12, 56, 46, 79, 61, + 49, 57, 79, 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, + 56, 45, 58, 59, 60, 61, 62, 63, 64, 65, + 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, + 21, 71, 72, 73, 74, 75, 58, 59, 60, 61, + 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, + 72, 73, 74, 75, 45, 48, 36, 48, 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, 65, 66, 67, 68, 69, + 70, 71, 72, 73, 74, 75, 69, 70, 71, 72, + 73, 74, 75, 16, 61, 123 +}; + +/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing + symbol of state STATE-NUM. */ +static const yytype_uint8 yystos[] = { + 0, 11, 17, 18, 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, 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, 88, 86, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 48, 48, + 57, 93, 94, 95, 93, 92, 88, 98, 56, 101, + 12, 12, 12, 14, 15, 8, 13, 15, 56, 57, + 88, 102, 12, 92, 45, 11, 45, 71, 96, 48, + 97, 93, 88, 56, 16, 96, 96, 14, 71, 72, + 73, 74, 75, 16, 48, 56, 102, 12, 96, 96, + 96, 96, 96 +}; + +#define yyerrok (yyerrstatus = 0) +#define yyclearin (yychar = YYEMPTY) +#define YYEMPTY (-2) +#define YYEOF 0 + +#define YYACCEPT goto yyacceptlab +#define YYABORT goto yyabortlab +#define YYERROR goto yyerrorlab + + +/* Like YYERROR except do call yyerror. This remains here temporarily + to ease the transition to the new meaning of YYERROR, for GCC. + Once GCC version 2 has supplanted version 1, this can go. However, + YYFAIL appears to be in use. Nevertheless, it is formally deprecated + in Bison 2.4.2's NEWS entry, where a plan to phase it out is + discussed. */ + +#define YYFAIL goto yyerrlab +#if defined YYFAIL +/* This is here to suppress warnings from the GCC cpp's + -Wunused-macros. Normally we don't worry about that warning, but + some users do, and we want to make it easy for users to remove + YYFAIL uses, which will produce warnings from Bison 2.5. */ +#endif + +#define YYRECOVERING() (!!yyerrstatus) + +#define YYBACKUP(Token, Value) \ +do \ + if (yychar == YYEMPTY) \ + { \ + yychar = (Token); \ + yylval = (Value); \ + YYPOPSTACK (yylen); \ + yystate = *yyssp; \ + goto yybackup; \ + } \ + else \ + { \ + yyerror (&yylloc, ctx, scanner, YY_("syntax error: cannot back up")); \ + YYERROR; \ + } \ +while (YYID (0)) + +/* Error token number */ +#define YYTERROR 1 +#define YYERRCODE 256 + + +/* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N]. + If N is 0, then set CURRENT to the empty location which ends + the previous symbol: RHS[0] (always defined). */ + +#ifndef YYLLOC_DEFAULT +# define YYLLOC_DEFAULT(Current, Rhs, N) \ + do \ + if (YYID (N)) \ + { \ + (Current).first_line = YYRHSLOC (Rhs, 1).first_line; \ + (Current).first_column = YYRHSLOC (Rhs, 1).first_column; \ + (Current).last_line = YYRHSLOC (Rhs, N).last_line; \ + (Current).last_column = YYRHSLOC (Rhs, N).last_column; \ + } \ + else \ + { \ + (Current).first_line = (Current).last_line = \ + YYRHSLOC (Rhs, 0).last_line; \ + (Current).first_column = (Current).last_column = \ + YYRHSLOC (Rhs, 0).last_column; \ + } \ + while (YYID (0)) +#endif + +#define YYRHSLOC(Rhs, K) ((Rhs)[K]) + + +/* YY_LOCATION_PRINT -- Print the location on the stream. + This macro was not mandated originally: define only if we know + we won't break user code: when these are the locations we know. */ + +#ifndef YY_LOCATION_PRINT +# if defined PROMELA_LTYPE_IS_TRIVIAL && PROMELA_LTYPE_IS_TRIVIAL + +/* Print *YYLOCP on YYO. Private, do not rely on its existence. */ + +__attribute__((__unused__)) +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static unsigned +yy_location_print_ (FILE *yyo, YYLTYPE const * const yylocp) +#else +static unsigned +yy_location_print_ (yyo, yylocp) +FILE *yyo; +YYLTYPE const * const yylocp; +#endif +{ + unsigned res = 0; + int end_col = 0 != yylocp->last_column ? yylocp->last_column - 1 : 0; + if (0 <= yylocp->first_line) { + res += fprintf (yyo, "%d", yylocp->first_line); + if (0 <= yylocp->first_column) + res += fprintf (yyo, ".%d", yylocp->first_column); + } + if (0 <= yylocp->last_line) { + if (yylocp->first_line < yylocp->last_line) { + res += fprintf (yyo, "-%d", yylocp->last_line); + if (0 <= end_col) + res += fprintf (yyo, ".%d", end_col); + } else if (0 <= end_col && yylocp->first_column < end_col) + res += fprintf (yyo, "-%d", end_col); + } + return res; +} + +# define YY_LOCATION_PRINT(File, Loc) \ + yy_location_print_ (File, &(Loc)) + +# else +# define YY_LOCATION_PRINT(File, Loc) ((void) 0) +# endif +#endif + + +/* YYLEX -- calling `yylex' with the right arguments. */ +#ifdef YYLEX_PARAM +# define YYLEX yylex (&yylval, &yylloc, YYLEX_PARAM) +#else +# define YYLEX yylex (&yylval, &yylloc, scanner) +#endif + +/* Enable debugging if requested. */ +#if PROMELA_DEBUG + +# ifndef YYFPRINTF +# include /* INFRINGES ON USER NAME SPACE */ +# define YYFPRINTF fprintf +# endif + +# define YYDPRINTF(Args) \ +do { \ + if (yydebug) \ + YYFPRINTF Args; \ +} while (YYID (0)) + +# define YY_SYMBOL_PRINT(Title, Type, Value, Location) \ +do { \ + if (yydebug) \ + { \ + YYFPRINTF (stderr, "%s ", Title); \ + yy_symbol_print (stderr, \ + Type, Value, Location, ctx, scanner); \ + YYFPRINTF (stderr, "\n"); \ + } \ +} while (YYID (0)) + + +/*--------------------------------. +| Print this symbol on YYOUTPUT. | +`--------------------------------*/ + +/*ARGSUSED*/ +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static void +yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, YYLTYPE const * const yylocationp, uscxml::PromelaParser* ctx, void * scanner) +#else +static void +yy_symbol_value_print (yyoutput, yytype, yyvaluep, yylocationp, ctx, scanner) +FILE *yyoutput; +int yytype; +YYSTYPE const * const yyvaluep; +YYLTYPE const * const yylocationp; +uscxml::PromelaParser* ctx; +void * scanner; +#endif +{ + FILE *yyo = yyoutput; + YYUSE (yyo); + if (!yyvaluep) + return; + YYUSE (yylocationp); + YYUSE (ctx); + YYUSE (scanner); +# ifdef YYPRINT + if (yytype < YYNTOKENS) + YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep); +# else + YYUSE (yyoutput); +# endif + YYUSE (yytype); +} + + +/*--------------------------------. +| Print this symbol on YYOUTPUT. | +`--------------------------------*/ + +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static void +yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, YYLTYPE const * const yylocationp, uscxml::PromelaParser* ctx, void * scanner) +#else +static void +yy_symbol_print (yyoutput, yytype, yyvaluep, yylocationp, ctx, scanner) +FILE *yyoutput; +int yytype; +YYSTYPE const * const yyvaluep; +YYLTYPE const * const yylocationp; +uscxml::PromelaParser* ctx; +void * scanner; +#endif +{ + if (yytype < YYNTOKENS) + YYFPRINTF (yyoutput, "token %s (", yytname[yytype]); + else + YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]); + + YY_LOCATION_PRINT (yyoutput, *yylocationp); + YYFPRINTF (yyoutput, ": "); + yy_symbol_value_print (yyoutput, yytype, yyvaluep, yylocationp, ctx, scanner); + YYFPRINTF (yyoutput, ")"); +} + +/*------------------------------------------------------------------. +| yy_stack_print -- Print the state stack from its BOTTOM up to its | +| TOP (included). | +`------------------------------------------------------------------*/ + +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static void +yy_stack_print (yytype_int16 *yybottom, yytype_int16 *yytop) +#else +static void +yy_stack_print (yybottom, yytop) +yytype_int16 *yybottom; +yytype_int16 *yytop; +#endif +{ + YYFPRINTF (stderr, "Stack now"); + for (; yybottom <= yytop; yybottom++) { + int yybot = *yybottom; + YYFPRINTF (stderr, " %d", yybot); + } + YYFPRINTF (stderr, "\n"); +} + +# define YY_STACK_PRINT(Bottom, Top) \ +do { \ + if (yydebug) \ + yy_stack_print ((Bottom), (Top)); \ +} while (YYID (0)) + + +/*------------------------------------------------. +| Report that the YYRULE is going to be reduced. | +`------------------------------------------------*/ + +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static void +yy_reduce_print (YYSTYPE *yyvsp, YYLTYPE *yylsp, int yyrule, uscxml::PromelaParser* ctx, void * scanner) +#else +static void +yy_reduce_print (yyvsp, yylsp, yyrule, ctx, scanner) +YYSTYPE *yyvsp; +YYLTYPE *yylsp; +int yyrule; +uscxml::PromelaParser* ctx; +void * scanner; +#endif +{ + int yynrhs = yyr2[yyrule]; + int yyi; + unsigned long int yylno = yyrline[yyrule]; + YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n", + yyrule - 1, yylno); + /* The symbols being reduced. */ + for (yyi = 0; yyi < yynrhs; yyi++) { + YYFPRINTF (stderr, " $%d = ", yyi + 1); + yy_symbol_print (stderr, yyrhs[yyprhs[yyrule] + yyi], + &(yyvsp[(yyi + 1) - (yynrhs)]) + , &(yylsp[(yyi + 1) - (yynrhs)]) , ctx, scanner); + YYFPRINTF (stderr, "\n"); + } +} + +# define YY_REDUCE_PRINT(Rule) \ +do { \ + if (yydebug) \ + yy_reduce_print (yyvsp, yylsp, Rule, ctx, scanner); \ +} while (YYID (0)) + +/* Nonzero means print parse trace. It is left uninitialized so that + multiple parsers can coexist. */ +int yydebug; +#else /* !PROMELA_DEBUG */ +# define YYDPRINTF(Args) +# define YY_SYMBOL_PRINT(Title, Type, Value, Location) +# define YY_STACK_PRINT(Bottom, Top) +# define YY_REDUCE_PRINT(Rule) +#endif /* !PROMELA_DEBUG */ + + +/* YYINITDEPTH -- initial size of the parser's stacks. */ +#ifndef YYINITDEPTH +# define YYINITDEPTH 200 +#endif + +/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only + if the built-in stack extension method is used). + + Do not make this value too large; the results are undefined if + YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH) + evaluated with infinite-precision integer arithmetic. */ + +#ifndef YYMAXDEPTH +# define YYMAXDEPTH 10000 +#endif + + +#if YYERROR_VERBOSE + +# ifndef yystrlen +# if defined __GLIBC__ && defined _STRING_H +# define yystrlen strlen +# else +/* Return the length of YYSTR. */ +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static YYSIZE_T +yystrlen (const char *yystr) +#else +static YYSIZE_T +yystrlen (yystr) +const char *yystr; +#endif +{ + YYSIZE_T yylen; + for (yylen = 0; yystr[yylen]; yylen++) + continue; + return yylen; +} +# endif +# endif + +# ifndef yystpcpy +# if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE +# define yystpcpy stpcpy +# else +/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in + YYDEST. */ +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static char * +yystpcpy (char *yydest, const char *yysrc) +#else +static char * +yystpcpy (yydest, yysrc) +char *yydest; +const char *yysrc; +#endif +{ + char *yyd = yydest; + const char *yys = yysrc; + + while ((*yyd++ = *yys++) != '\0') + continue; + + return yyd - 1; +} +# endif +# endif + +# ifndef yytnamerr +/* Copy to YYRES the contents of YYSTR after stripping away unnecessary + quotes and backslashes, so that it's suitable for yyerror. The + heuristic is that double-quoting is unnecessary unless the string + contains an apostrophe, a comma, or backslash (other than + backslash-backslash). YYSTR is taken from yytname. If YYRES is + null, do not copy; instead, return the length of what the result + would have been. */ +static YYSIZE_T +yytnamerr (char *yyres, const char *yystr) { + if (*yystr == '"') { + YYSIZE_T yyn = 0; + char const *yyp = yystr; + + for (;;) + switch (*++yyp) { + case '\'': + case ',': + goto do_not_strip_quotes; + + case '\\': + if (*++yyp != '\\') + goto do_not_strip_quotes; + /* Fall through. */ + default: + if (yyres) + yyres[yyn] = *yyp; + yyn++; + break; + + case '"': + if (yyres) + yyres[yyn] = '\0'; + return yyn; + } +do_not_strip_quotes: + ; + } + + if (! yyres) + return yystrlen (yystr); + + return yystpcpy (yyres, yystr) - yyres; +} +# endif + +/* Copy into *YYMSG, which is of size *YYMSG_ALLOC, an error message + about the unexpected token YYTOKEN for the state stack whose top is + YYSSP. + + Return 0 if *YYMSG was successfully written. Return 1 if *YYMSG is + not large enough to hold the message. In that case, also set + *YYMSG_ALLOC to the required number of bytes. Return 2 if the + required number of bytes is too large to store. */ +static int +yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg, + yytype_int16 *yyssp, int yytoken) { + YYSIZE_T yysize0 = yytnamerr (YY_NULL, yytname[yytoken]); + YYSIZE_T yysize = yysize0; + enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 }; + /* Internationalized format string. */ + const char *yyformat = YY_NULL; + /* Arguments of yyformat. */ + char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM]; + /* Number of reported tokens (one for the "unexpected", one per + "expected"). */ + int yycount = 0; + + /* There are many possibilities here to consider: + - Assume YYFAIL is not used. It's too flawed to consider. See + + for details. YYERROR is fine as it does not invoke this + function. + - If this state is a consistent state with a default action, then + the only way this function was invoked is if the default action + is an error action. In that case, don't check for expected + tokens because there are none. + - The only way there can be no lookahead present (in yychar) is if + this state is a consistent state with a default action. Thus, + detecting the absence of a lookahead is sufficient to determine + that there is no unexpected or expected token to report. In that + case, just report a simple "syntax error". + - Don't assume there isn't a lookahead just because this state is a + consistent state with a default action. There might have been a + previous inconsistent state, consistent state with a non-default + action, or user semantic action that manipulated yychar. + - Of course, the expected token list depends on states to have + correct lookahead information, and it depends on the parser not + to perform extra reductions after fetching a lookahead from the + scanner and before detecting a syntax error. Thus, state merging + (from LALR or IELR) and default reductions corrupt the expected + token list. However, the list is correct for canonical LR with + one exception: it will still contain any token that will not be + accepted due to an error action in a later state. + */ + if (yytoken != YYEMPTY) { + int yyn = yypact[*yyssp]; + yyarg[yycount++] = yytname[yytoken]; + if (!yypact_value_is_default (yyn)) { + /* Start YYX at -YYN if negative to avoid negative indexes in + YYCHECK. In other words, skip the first -YYN actions for + this state because they are default actions. */ + int yyxbegin = yyn < 0 ? -yyn : 0; + /* Stay within bounds of both yycheck and yytname. */ + int yychecklim = YYLAST - yyn + 1; + int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS; + int yyx; + + for (yyx = yyxbegin; yyx < yyxend; ++yyx) + if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR + && !yytable_value_is_error (yytable[yyx + yyn])) { + if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM) { + yycount = 1; + yysize = yysize0; + break; + } + yyarg[yycount++] = yytname[yyx]; + { + YYSIZE_T yysize1 = yysize + yytnamerr (YY_NULL, yytname[yyx]); + if (! (yysize <= yysize1 + && yysize1 <= YYSTACK_ALLOC_MAXIMUM)) + return 2; + yysize = yysize1; + } + } + } + } + + switch (yycount) { +# define YYCASE_(N, S) \ + case N: \ + yyformat = S; \ + break + YYCASE_(0, YY_("syntax error")); + YYCASE_(1, YY_("syntax error, unexpected %s")); + YYCASE_(2, YY_("syntax error, unexpected %s, expecting %s")); + YYCASE_(3, YY_("syntax error, unexpected %s, expecting %s or %s")); + YYCASE_(4, YY_("syntax error, unexpected %s, expecting %s or %s or %s")); + YYCASE_(5, YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s")); +# undef YYCASE_ + } + + { + YYSIZE_T yysize1 = yysize + yystrlen (yyformat); + if (! (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM)) + return 2; + yysize = yysize1; + } + + if (*yymsg_alloc < yysize) { + *yymsg_alloc = 2 * yysize; + if (! (yysize <= *yymsg_alloc + && *yymsg_alloc <= YYSTACK_ALLOC_MAXIMUM)) + *yymsg_alloc = YYSTACK_ALLOC_MAXIMUM; + return 1; + } + + /* Avoid sprintf, as that infringes on the user's name space. + Don't have undefined behavior even if the translation + produced a string with the wrong number of "%s"s. */ + { + char *yyp = *yymsg; + int yyi = 0; + while ((*yyp = *yyformat) != '\0') + if (*yyp == '%' && yyformat[1] == 's' && yyi < yycount) { + yyp += yytnamerr (yyp, yyarg[yyi++]); + yyformat += 2; + } else { + yyp++; + yyformat++; + } + } + return 0; +} +#endif /* YYERROR_VERBOSE */ + +/*-----------------------------------------------. +| Release the memory associated to this symbol. | +`-----------------------------------------------*/ + +/*ARGSUSED*/ +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static void +yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep, YYLTYPE *yylocationp, uscxml::PromelaParser* ctx, void * scanner) +#else +static void +yydestruct (yymsg, yytype, yyvaluep, yylocationp, ctx, scanner) +const char *yymsg; +int yytype; +YYSTYPE *yyvaluep; +YYLTYPE *yylocationp; +uscxml::PromelaParser* ctx; +void * scanner; +#endif +{ + YYUSE (yyvaluep); + YYUSE (yylocationp); + YYUSE (ctx); + YYUSE (scanner); + + if (!yymsg) + yymsg = "Deleting"; + YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp); + + YYUSE (yytype); +} + + + + +/*----------. +| yyparse. | +`----------*/ + +#ifdef YYPARSE_PARAM +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +int +yyparse (void *YYPARSE_PARAM) +#else +int +yyparse (YYPARSE_PARAM) +void *YYPARSE_PARAM; +#endif +#else /* ! YYPARSE_PARAM */ +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +int +yyparse (uscxml::PromelaParser* ctx, void * scanner) +#else +int +yyparse (ctx, scanner) +uscxml::PromelaParser* ctx; +void * scanner; +#endif +#endif +{ + /* The lookahead symbol. */ + int yychar; + + +#if defined __GNUC__ && 407 <= __GNUC__ * 100 + __GNUC_MINOR__ + /* Suppress an incorrect diagnostic about yylval being uninitialized. */ +# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN \ + _Pragma ("GCC diagnostic push") \ + _Pragma ("GCC diagnostic ignored \"-Wuninitialized\"")\ + _Pragma ("GCC diagnostic ignored \"-Wmaybe-uninitialized\"") +# define YY_IGNORE_MAYBE_UNINITIALIZED_END \ + _Pragma ("GCC diagnostic pop") +#else + /* Default value used for initialization, for pacifying older GCCs + or non-GCC compilers. */ + static YYSTYPE yyval_default; +# define YY_INITIAL_VALUE(Value) = Value +#endif + static YYLTYPE yyloc_default +# if defined PROMELA_LTYPE_IS_TRIVIAL && PROMELA_LTYPE_IS_TRIVIAL + = { 1, 1, 1, 1 } +# endif + ; +#ifndef YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN +# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN +# define YY_IGNORE_MAYBE_UNINITIALIZED_END +#endif +#ifndef YY_INITIAL_VALUE +# define YY_INITIAL_VALUE(Value) /* Nothing. */ +#endif + + /* The semantic value of the lookahead symbol. */ + YYSTYPE yylval YY_INITIAL_VALUE(yyval_default); + + /* Location data for the lookahead symbol. */ + YYLTYPE yylloc = yyloc_default; + + + /* Number of syntax errors so far. */ + int yynerrs; + + int yystate; + /* Number of tokens to shift before error messages enabled. */ + int yyerrstatus; + + /* The stacks and their tools: + `yyss': related to states. + `yyvs': related to semantic values. + `yyls': related to locations. + + Refer to the stacks through separate pointers, to allow yyoverflow + to reallocate them elsewhere. */ + + /* The state stack. */ + yytype_int16 yyssa[YYINITDEPTH]; + yytype_int16 *yyss; + yytype_int16 *yyssp; + + /* The semantic value stack. */ + YYSTYPE yyvsa[YYINITDEPTH]; + YYSTYPE *yyvs; + YYSTYPE *yyvsp; + + /* The location stack. */ + YYLTYPE yylsa[YYINITDEPTH]; + YYLTYPE *yyls; + YYLTYPE *yylsp; + + /* The locations where the error started and ended. */ + YYLTYPE yyerror_range[3]; + + YYSIZE_T yystacksize; + + int yyn; + int yyresult; + /* Lookahead token as an internal (translated) token number. */ + int yytoken = 0; + /* The variables used to return semantic value and location from the + action routines. */ + YYSTYPE yyval; + YYLTYPE yyloc; + +#if YYERROR_VERBOSE + /* Buffer for error messages, and its allocated size. */ + char yymsgbuf[128]; + char *yymsg = yymsgbuf; + YYSIZE_T yymsg_alloc = sizeof yymsgbuf; +#endif + +#define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N), yylsp -= (N)) + + /* The number of symbols on the RHS of the reduced rule. + Keep to zero when no symbol should be popped. */ + int yylen = 0; + + yyssp = yyss = yyssa; + yyvsp = yyvs = yyvsa; + yylsp = yyls = yylsa; + yystacksize = YYINITDEPTH; + + YYDPRINTF ((stderr, "Starting parse\n")); + + yystate = 0; + yyerrstatus = 0; + yynerrs = 0; + yychar = YYEMPTY; /* Cause a token to be read. */ + yylsp[0] = yylloc; + goto yysetstate; + + /*------------------------------------------------------------. + | yynewstate -- Push a new state, which is found in yystate. | + `------------------------------------------------------------*/ +yynewstate: + /* In all cases, when you get here, the value and location stacks + have just been pushed. So pushing a state here evens the stacks. */ + yyssp++; + +yysetstate: + *yyssp = yystate; + + if (yyss + yystacksize - 1 <= yyssp) { + /* Get the current used size of the three stacks, in elements. */ + YYSIZE_T yysize = yyssp - yyss + 1; + +#ifdef yyoverflow + { + /* Give user a chance to reallocate the stack. Use copies of + these so that the &'s don't force the real ones into + memory. */ + YYSTYPE *yyvs1 = yyvs; + yytype_int16 *yyss1 = yyss; + YYLTYPE *yyls1 = yyls; + + /* Each stack pointer address is followed by the size of the + data in use in that stack, in bytes. This used to be a + conditional around just the two extra args, but that might + be undefined if yyoverflow is a macro. */ + yyoverflow (YY_("memory exhausted"), + &yyss1, yysize * sizeof (*yyssp), + &yyvs1, yysize * sizeof (*yyvsp), + &yyls1, yysize * sizeof (*yylsp), + &yystacksize); + + yyls = yyls1; + yyss = yyss1; + yyvs = yyvs1; + } +#else /* no yyoverflow */ +# ifndef YYSTACK_RELOCATE + goto yyexhaustedlab; +# else + /* Extend the stack our own way. */ + if (YYMAXDEPTH <= yystacksize) + goto yyexhaustedlab; + yystacksize *= 2; + if (YYMAXDEPTH < yystacksize) + yystacksize = YYMAXDEPTH; + + { + yytype_int16 *yyss1 = yyss; + union yyalloc *yyptr = + (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); + if (! yyptr) + goto yyexhaustedlab; + YYSTACK_RELOCATE (yyss_alloc, yyss); + YYSTACK_RELOCATE (yyvs_alloc, yyvs); + YYSTACK_RELOCATE (yyls_alloc, yyls); +# undef YYSTACK_RELOCATE + if (yyss1 != yyssa) + YYSTACK_FREE (yyss1); + } +# endif +#endif /* no yyoverflow */ + + yyssp = yyss + yysize - 1; + yyvsp = yyvs + yysize - 1; + yylsp = yyls + yysize - 1; + + YYDPRINTF ((stderr, "Stack size increased to %lu\n", + (unsigned long int) yystacksize)); + + if (yyss + yystacksize - 1 <= yyssp) + YYABORT; + } + + YYDPRINTF ((stderr, "Entering state %d\n", yystate)); + + if (yystate == YYFINAL) + YYACCEPT; + + goto yybackup; + + /*-----------. + | yybackup. | + `-----------*/ +yybackup: + + /* Do appropriate processing given the current state. Read a + lookahead token if we need one and don't already have one. */ + + /* First try to decide what to do without reference to lookahead token. */ + yyn = yypact[yystate]; + if (yypact_value_is_default (yyn)) + goto yydefault; + + /* Not known => get a lookahead token if don't already have one. */ + + /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol. */ + if (yychar == YYEMPTY) { + YYDPRINTF ((stderr, "Reading a token: ")); + yychar = YYLEX; + } + + if (yychar <= YYEOF) { + yychar = yytoken = YYEOF; + YYDPRINTF ((stderr, "Now at end of input.\n")); + } else { + yytoken = YYTRANSLATE (yychar); + YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc); + } + + /* If the proper action on seeing token YYTOKEN is to reduce or to + detect an error, take that action. */ + yyn += yytoken; + if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken) + goto yydefault; + yyn = yytable[yyn]; + if (yyn <= 0) { + if (yytable_value_is_error (yyn)) + goto yyerrlab; + yyn = -yyn; + goto yyreduce; + } + + /* Count tokens shifted since error; after three, turn off error + status. */ + if (yyerrstatus) + yyerrstatus--; + + /* Shift the lookahead token. */ + YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc); + + /* Discard the shifted token. */ + yychar = YYEMPTY; + + yystate = yyn; + YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN + *++yyvsp = yylval; + YY_IGNORE_MAYBE_UNINITIALIZED_END + *++yylsp = yylloc; + goto yynewstate; + + + /*-----------------------------------------------------------. + | yydefault -- do the default action for the current state. | + `-----------------------------------------------------------*/ +yydefault: + yyn = yydefact[yystate]; + if (yyn == 0) + goto yyerrlab; + goto yyreduce; + + + /*-----------------------------. + | yyreduce -- Do a reduction. | + `-----------------------------*/ +yyreduce: + /* yyn is the number of a rule to reduce with. */ + yylen = yyr2[yyn]; + + /* If YYLEN is nonzero, implement the default value of the action: + `$$ = $1'. + + Otherwise, the following line sets YYVAL to garbage. + This behavior is undocumented and Bison + users should not rely upon it. Assigning to YYVAL + unconditionally makes the parser a bit smaller, and it avoids a + GCC warning that YYVAL may be used uninitialized. */ + yyval = yyvsp[1-yylen]; + + /* Default location. */ + YYLLOC_DEFAULT (yyloc, (yylsp - yylen), yylen); + YY_REDUCE_PRINT (yyn); + switch (yyn) { + case 2: + /* Line 1787 of yacc.c */ +#line 85 "promela.ypp" + { + ctx->ast = (yyvsp[(1) - (1)].node); + ctx->type = PromelaParser::PROMELA_DECL; + } + break; + + case 3: + /* Line 1787 of yacc.c */ +#line 89 "promela.ypp" + { + ctx->ast = (yyvsp[(1) - (1)].node); + ctx->type = PromelaParser::PROMELA_EXPR; + } + break; + + case 4: + /* Line 1787 of yacc.c */ +#line 93 "promela.ypp" + { + ctx->ast = (yyvsp[(1) - (1)].node); + ctx->type = PromelaParser::PROMELA_STMNT; + } + break; + + case 5: + /* Line 1787 of yacc.c */ +#line 99 "promela.ypp" + { + (yyval.node) = (yyvsp[(1) - (1)].node); + } + break; + + case 6: + /* Line 1787 of yacc.c */ +#line 102 "promela.ypp" + { + (yyval.node) = ctx->value(PML_NAME, (void*)&((yylsp[(1) - (1)])), (yyvsp[(1) - (1)].value)); + free((yyvsp[(1) - (1)].value)); + } + break; + + case 7: + /* Line 1787 of yacc.c */ +#line 103 "promela.ypp" + { + (yyval.node) = ctx->node(PML_VAR_ARRAY, 2, ctx->value(PML_NAME, (void*)&((yylsp[(1) - (4)])), (yyvsp[(1) - (4)].value)), (yyvsp[(3) - (4)].node)); + free((yyvsp[(1) - (4)].value)); + } + break; + + case 8: + /* Line 1787 of yacc.c */ +#line 107 "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 { + (yyval.node) = (yyvsp[(1) - (2)].node); + } + } + break; + + case 9: + /* Line 1787 of yacc.c */ +#line 121 "promela.ypp" + { + (yyval.node) = NULL; + } + break; + + case 10: + /* Line 1787 of yacc.c */ +#line 122 "promela.ypp" + { + (yyval.node) = (yyvsp[(2) - (2)].node); + } + break; + + case 11: + /* Line 1787 of yacc.c */ +#line 132 "promela.ypp" + { + (yyval.node) = (yyvsp[(2) - (3)].node); + } + break; + + case 12: + /* Line 1787 of yacc.c */ +#line 133 "promela.ypp" + { + (yyval.node) = ctx->node(PML_PLUS, 2, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node)); + } + break; + + case 13: + /* Line 1787 of yacc.c */ +#line 134 "promela.ypp" + { + (yyval.node) = ctx->node(PML_MINUS, 2, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node)); + } + break; + + case 14: + /* Line 1787 of yacc.c */ +#line 135 "promela.ypp" + { + (yyval.node) = ctx->node(PML_TIMES, 2, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node)); + } + break; + + case 15: + /* Line 1787 of yacc.c */ +#line 136 "promela.ypp" + { + (yyval.node) = ctx->node(PML_DIVIDE, 2, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node)); + } + break; + + case 16: + /* Line 1787 of yacc.c */ +#line 137 "promela.ypp" + { + (yyval.node) = ctx->node(PML_MODULO, 2, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node)); + } + break; + + case 17: + /* Line 1787 of yacc.c */ +#line 138 "promela.ypp" + { + (yyval.node) = ctx->node(PML_BITAND, 2, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node)); + } + break; + + case 18: + /* Line 1787 of yacc.c */ +#line 139 "promela.ypp" + { + (yyval.node) = ctx->node(PML_BITXOR, 2, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node)); + } + break; + + case 19: + /* Line 1787 of yacc.c */ +#line 140 "promela.ypp" + { + (yyval.node) = ctx->node(PML_BITOR, 2, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node)); + } + break; + + case 20: + /* Line 1787 of yacc.c */ +#line 141 "promela.ypp" + { + (yyval.node) = ctx->node(PML_GT, 2, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node)); + } + break; + + case 21: + /* Line 1787 of yacc.c */ +#line 142 "promela.ypp" + { + (yyval.node) = ctx->node(PML_LT, 2, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node)); + } + break; + + case 22: + /* Line 1787 of yacc.c */ +#line 143 "promela.ypp" + { + (yyval.node) = ctx->node(PML_GE, 2, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node)); + } + break; + + case 23: + /* Line 1787 of yacc.c */ +#line 144 "promela.ypp" + { + (yyval.node) = ctx->node(PML_LE, 2, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node)); + } + break; + + case 24: + /* Line 1787 of yacc.c */ +#line 145 "promela.ypp" + { + (yyval.node) = ctx->node(PML_EQ, 2, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node)); + } + break; + + case 25: + /* Line 1787 of yacc.c */ +#line 146 "promela.ypp" + { + (yyval.node) = ctx->node(PML_NE, 2, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node)); + } + break; + + case 26: + /* Line 1787 of yacc.c */ +#line 147 "promela.ypp" + { + (yyval.node) = ctx->node(PML_AND, 2, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node)); + } + break; + + case 27: + /* Line 1787 of yacc.c */ +#line 148 "promela.ypp" + { + (yyval.node) = ctx->node(PML_OR, 2, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node)); + } + break; + + case 28: + /* Line 1787 of yacc.c */ +#line 149 "promela.ypp" + { + (yyval.node) = ctx->node(PML_LSHIFT, 2, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node)); + } + break; + + case 29: + /* Line 1787 of yacc.c */ +#line 150 "promela.ypp" + { + (yyval.node) = ctx->node(PML_RSHIFT, 2, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node)); + } + break; + + case 30: + /* Line 1787 of yacc.c */ +#line 151 "promela.ypp" + { + (yyval.node) = ctx->node(PML_NEG, 1, (yyvsp[(2) - (2)].node)); + } + break; + + case 31: + /* Line 1787 of yacc.c */ +#line 152 "promela.ypp" + { + (yyval.node) = ctx->node(PML_MINUS, 1, (yyvsp[(2) - (2)].node)); + } + break; + + case 32: + /* Line 1787 of yacc.c */ +#line 154 "promela.ypp" + { + (yyval.node) = ctx->node(PML_LEN, 1, (yyvsp[(3) - (4)].node)); + } + break; + + case 33: + /* Line 1787 of yacc.c */ +#line 155 "promela.ypp" + { + (yyval.node) = (yyvsp[(1) - (1)].node); + } + break; + + case 34: + /* Line 1787 of yacc.c */ +#line 156 "promela.ypp" + { + (yyval.node) = ctx->value(PML_CONST, (void*)&((yylsp[(1) - (1)])), (yyvsp[(1) - (1)].value)); + free((yyvsp[(1) - (1)].value)); + } + break; + + case 35: + /* Line 1787 of yacc.c */ +#line 157 "promela.ypp" + { + /* Non standard promela for string literals */ + (yyval.node) = ctx->value(PML_STRING, (void*)&((yylsp[(1) - (1)])), (yyvsp[(1) - (1)].value)); + free((yyvsp[(1) - (1)].value)); + } + break; + + case 36: + /* Line 1787 of yacc.c */ +#line 163 "promela.ypp" + { + (yyval.node) = ctx->node(PML_SHOW, 0); + } + break; + + case 37: + /* Line 1787 of yacc.c */ +#line 164 "promela.ypp" + { + (yyval.node) = ctx->node(PML_HIDDEN, 0); + } + break; + + case 38: + /* Line 1787 of yacc.c */ +#line 165 "promela.ypp" + { + (yyval.node) = ctx->node(PML_SHOW, 0); + } + break; + + case 39: + /* Line 1787 of yacc.c */ +#line 166 "promela.ypp" + { + (yyval.node) = ctx->node(PML_ISLOCAL, 0); + } + break; + + case 40: + /* Line 1787 of yacc.c */ +#line 169 "promela.ypp" + { + (yyval.node) = ctx->node(PML_DECL, 3, (yyvsp[(1) - (3)].node), ctx->value(PML_TYPE, (void*)&((yylsp[(2) - (3)])), (yyvsp[(2) - (3)].value)), (yyvsp[(3) - (3)].node)); + free((yyvsp[(2) - (3)].value)); + } + break; + + case 41: + /* Line 1787 of yacc.c */ +#line 170 "promela.ypp" + { + (yyval.node) = ctx->node(PML_UNAME, 2, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node)); + } + break; + + case 42: + /* Line 1787 of yacc.c */ +#line 171 "promela.ypp" + { + (yyval.node) = ctx->node(PML_DECL, 3, (yyvsp[(1) - (6)].node), ctx->value(PML_TYPE, (void*)&((yylsp[(2) - (6)])), (yyvsp[(2) - (6)].value)), (yyvsp[(5) - (6)].node)); + free((yyvsp[(2) - (6)].value)); + } + break; + + case 43: + /* Line 1787 of yacc.c */ +#line 172 "promela.ypp" + { + (yyval.node) = (yyvsp[(2) - (2)].node); + } + break; + + case 44: + /* Line 1787 of yacc.c */ +#line 175 "promela.ypp" + { + (yyval.node) = ctx->node(PML_TYPEDEF, 2, ctx->value(PML_NAME, (void*)&((yylsp[(2) - (5)])), (yyvsp[(2) - (5)].value)), (yyvsp[(4) - (5)].node)); + } + break; + + case 45: + /* Line 1787 of yacc.c */ +#line 178 "promela.ypp" + { + (yyval.node) = (yyvsp[(1) - (1)].node); + } + break; + + case 46: + /* Line 1787 of yacc.c */ +#line 179 "promela.ypp" + { + (yyval.node) = (yyvsp[(1) - (2)].node); + } + break; + + case 47: + /* Line 1787 of yacc.c */ +#line 180 "promela.ypp" + { + (yyval.node) = ctx->node(PML_DECLLIST, 1, (yyvsp[(1) - (3)].node)); + if((yyvsp[(3) - (3)].node)->type == PML_DECLLIST) { + (yyval.node)->merge((yyvsp[(3) - (3)].node)); + delete (yyvsp[(3) - (3)].node); + } else { + (yyval.node)->push((yyvsp[(3) - (3)].node)); + } + } + break; + + case 48: + /* Line 1787 of yacc.c */ +#line 190 "promela.ypp" + { + (yyval.node) = ctx->node(PML_VARLIST, 1, (yyvsp[(1) - (1)].node)); + } + break; + + case 49: + /* Line 1787 of yacc.c */ +#line 191 "promela.ypp" + { + (yyval.node) = ctx->node(PML_VARLIST, 1, (yyvsp[(1) - (3)].node)); + (yyval.node)->merge((yyvsp[(3) - (3)].node)); + delete (yyvsp[(3) - (3)].node); + } + break; + + case 50: + /* Line 1787 of yacc.c */ +#line 194 "promela.ypp" + { + (yyval.node) = (yyvsp[(1) - (1)].node); + } + break; + + case 51: + /* Line 1787 of yacc.c */ +#line 195 "promela.ypp" + { + (yyval.node) = ctx->node(PML_ASGN, 2, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node)); + } + break; + + case 52: + /* Line 1787 of yacc.c */ +#line 198 "promela.ypp" + { + (yyval.node) = ctx->value(PML_NAME, (void*)&((yylsp[(1) - (1)])), (yyvsp[(1) - (1)].value)); + free((yyvsp[(1) - (1)].value)); + } + break; + + case 53: + /* Line 1787 of yacc.c */ +#line 199 "promela.ypp" + { + (yyval.node) = ctx->node(PML_COLON, 2, ctx->value(PML_NAME, (void*)&((yylsp[(1) - (3)])), (yyvsp[(1) - (3)].value)), ctx->value(PML_CONST, (void*)&((yylsp[(3) - (3)])), (yyvsp[(3) - (3)].value))); + free((yyvsp[(1) - (3)].value)); + free((yyvsp[(3) - (3)].value)); + } + break; + + case 54: + /* Line 1787 of yacc.c */ +#line 200 "promela.ypp" + { + (yyval.node) = ctx->node(PML_VAR_ARRAY, 2, ctx->value(PML_NAME, (void*)&((yylsp[(1) - (4)])), (yyvsp[(1) - (4)].value)), (yyvsp[(3) - (4)].node)); + free((yyvsp[(1) - (4)].value)); + } + break; + + case 55: + /* Line 1787 of yacc.c */ +#line 203 "promela.ypp" + { + (yyval.node) = ctx->value(PML_CONST, (void*)&((yylsp[(1) - (1)])), (yyvsp[(1) - (1)].value)); + free((yyvsp[(1) - (1)].value)); + } + break; + + case 56: + /* Line 1787 of yacc.c */ +#line 204 "promela.ypp" + { + (yyval.node) = ctx->node(PML_MINUS, 1, (yyvsp[(2) - (2)].node)); + } + break; + + case 57: + /* Line 1787 of yacc.c */ +#line 205 "promela.ypp" + { + (yyval.node) = (yyvsp[(2) - (3)].node); + } + break; + + case 58: + /* Line 1787 of yacc.c */ +#line 206 "promela.ypp" + { + (yyval.node) = ctx->node(PML_PLUS, 2, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node)); + } + break; + + case 59: + /* Line 1787 of yacc.c */ +#line 207 "promela.ypp" + { + (yyval.node) = ctx->node(PML_MINUS, 2, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node)); + } + break; + + case 60: + /* Line 1787 of yacc.c */ +#line 208 "promela.ypp" + { + (yyval.node) = ctx->node(PML_TIMES, 2, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node)); + } + break; + + case 61: + /* Line 1787 of yacc.c */ +#line 209 "promela.ypp" + { + (yyval.node) = ctx->node(PML_DIVIDE, 2, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node)); + } + break; + + case 62: + /* Line 1787 of yacc.c */ +#line 210 "promela.ypp" + { + (yyval.node) = ctx->node(PML_MODULO, 2, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node)); + } + break; + + case 63: + /* Line 1787 of yacc.c */ +#line 213 "promela.ypp" + { + (yyval.node) = ctx->value(PML_NAME, (void*)&((yylsp[(1) - (1)])), (yyvsp[(1) - (1)].value)); + free((yyvsp[(1) - (1)].value)); + } + break; + + case 64: + /* Line 1787 of yacc.c */ +#line 214 "promela.ypp" + { + if ((yyvsp[(1) - (2)].node)->type == PML_NAME) { + (yyval.node) = ctx->node(PML_NAMELIST, 1, (yyvsp[(1) - (2)].node)); + (yyval.node)->push(ctx->value(PML_NAME, (void*)&((yylsp[(2) - (2)])), (yyvsp[(2) - (2)].value))); + } else { + (yyvsp[(1) - (2)].node)->push(ctx->value(PML_NAME, (void*)&((yylsp[(2) - (2)])), (yyvsp[(2) - (2)].value))); + } + free((yyvsp[(2) - (2)].value)); + } + break; + + case 65: + /* Line 1787 of yacc.c */ +#line 223 "promela.ypp" + { + (yyval.node) = (yyvsp[(1) - (2)].node); + } + break; + + case 66: + /* Line 1787 of yacc.c */ +#line 226 "promela.ypp" + { + (yyval.node) = (yyvsp[(1) - (1)].node); + } + break; + + case 67: + /* Line 1787 of yacc.c */ +#line 227 "promela.ypp" + { + (yyval.node) = (yyvsp[(1) - (2)].node); + } + break; + + case 68: + /* Line 1787 of yacc.c */ +#line 228 "promela.ypp" + { + (yyval.node) = ctx->node(PML_STMNT, 2, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node)); + } + break; + + case 69: + /* Line 1787 of yacc.c */ +#line 231 "promela.ypp" + { + (yyval.node) = (yyvsp[(1) - (1)].node); + } + break; + + case 70: + /* Line 1787 of yacc.c */ +#line 234 "promela.ypp" + { + (yyval.node) = ctx->node(PML_ASGN, 2, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node)); + } + break; + + case 71: + /* Line 1787 of yacc.c */ +#line 235 "promela.ypp" + { + (yyval.node) = ctx->node(PML_INCR, 1, (yyvsp[(1) - (2)].node)); + } + break; + + case 72: + /* Line 1787 of yacc.c */ +#line 236 "promela.ypp" + { + (yyval.node) = ctx->node(PML_DECR, 1, (yyvsp[(1) - (2)].node)); + } + break; + + case 73: + /* Line 1787 of yacc.c */ +#line 237 "promela.ypp" + { + (yyval.node) = ctx->node(PML_PRINT, 2, ctx->value(PML_STRING, (void*)&((yylsp[(3) - (5)])), (yyvsp[(3) - (5)].value)), (yyvsp[(4) - (5)].node)); + free((yyvsp[(3) - (5)].value)); + } + break; + + case 74: + /* Line 1787 of yacc.c */ +#line 238 "promela.ypp" + { + (yyval.node) = ctx->node(PML_PRINT, 1, (yyvsp[(3) - (4)].node)); + } + break; + + case 75: + /* Line 1787 of yacc.c */ +#line 239 "promela.ypp" + { + (yyval.node) = ctx->node(PML_PRINT, 1, ctx->value(PML_CONST, (void*)&((yylsp[(3) - (4)])), (yyvsp[(3) - (4)].value))); + free((yyvsp[(3) - (4)].value)); + } + break; + + case 76: + /* Line 1787 of yacc.c */ +#line 240 "promela.ypp" + { + (yyval.node) = ctx->node(PML_ASSERT, 1, (yyvsp[(2) - (2)].node)); + } + break; + + case 77: + /* Line 1787 of yacc.c */ +#line 241 "promela.ypp" + { + (yyval.node) = (yyvsp[(1) - (1)].node); + } + break; + + case 78: + /* Line 1787 of yacc.c */ +#line 244 "promela.ypp" + { + (yyval.node) = ctx->value(0, NULL, ""); + } + break; + + case 79: + /* Line 1787 of yacc.c */ +#line 245 "promela.ypp" + { + (yyval.node) = (yyvsp[(2) - (2)].node); + } + break; + + case 80: + /* Line 1787 of yacc.c */ +#line 248 "promela.ypp" + { + (yyval.node) = (yyvsp[(1) - (1)].node); + } + break; + + case 81: + /* Line 1787 of yacc.c */ +#line 249 "promela.ypp" + { + (yyval.node) = ctx->node(0, 2, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node)); + } + break; + + + /* Line 1787 of yacc.c */ +#line 2285 "promela.tab.cpp" + default: + break; + } + /* User semantic actions sometimes alter yychar, and that requires + that yytoken be updated with the new translation. We take the + approach of translating immediately before every use of yytoken. + One alternative is translating here after every semantic action, + but that translation would be missed if the semantic action invokes + YYABORT, YYACCEPT, or YYERROR immediately after altering yychar or + if it invokes YYBACKUP. In the case of YYABORT or YYACCEPT, an + incorrect destructor might then be invoked immediately. In the + case of YYERROR or YYBACKUP, subsequent parser actions might lead + to an incorrect destructor call or verbose syntax error message + before the lookahead is translated. */ + YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc); + + YYPOPSTACK (yylen); + yylen = 0; + YY_STACK_PRINT (yyss, yyssp); + + *++yyvsp = yyval; + *++yylsp = yyloc; + + /* Now `shift' the result of the reduction. Determine what state + that goes to, based on the state we popped back to and the rule + number reduced by. */ + + yyn = yyr1[yyn]; + + yystate = yypgoto[yyn - YYNTOKENS] + *yyssp; + if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp) + yystate = yytable[yystate]; + else + yystate = yydefgoto[yyn - YYNTOKENS]; + + goto yynewstate; + + + /*------------------------------------. + | yyerrlab -- here on detecting error | + `------------------------------------*/ +yyerrlab: + /* Make sure we have latest lookahead translation. See comments at + user semantic actions for why this is necessary. */ + yytoken = yychar == YYEMPTY ? YYEMPTY : YYTRANSLATE (yychar); + + /* If not already recovering from an error, report this error. */ + if (!yyerrstatus) { + ++yynerrs; +#if ! YYERROR_VERBOSE + yyerror (&yylloc, ctx, scanner, YY_("syntax error")); +#else +# define YYSYNTAX_ERROR yysyntax_error (&yymsg_alloc, &yymsg, \ + yyssp, yytoken) + { + char const *yymsgp = YY_("syntax error"); + int yysyntax_error_status; + yysyntax_error_status = YYSYNTAX_ERROR; + if (yysyntax_error_status == 0) + yymsgp = yymsg; + else if (yysyntax_error_status == 1) { + if (yymsg != yymsgbuf) + YYSTACK_FREE (yymsg); + yymsg = (char *) YYSTACK_ALLOC (yymsg_alloc); + if (!yymsg) { + yymsg = yymsgbuf; + yymsg_alloc = sizeof yymsgbuf; + yysyntax_error_status = 2; + } else { + yysyntax_error_status = YYSYNTAX_ERROR; + yymsgp = yymsg; + } + } + yyerror (&yylloc, ctx, scanner, yymsgp); + if (yysyntax_error_status == 2) + goto yyexhaustedlab; + } +# undef YYSYNTAX_ERROR +#endif + } + + yyerror_range[1] = yylloc; + + if (yyerrstatus == 3) { + /* If just tried and failed to reuse lookahead token after an + error, discard it. */ + + if (yychar <= YYEOF) { + /* Return failure if at end of input. */ + if (yychar == YYEOF) + YYABORT; + } else { + yydestruct ("Error: discarding", + yytoken, &yylval, &yylloc, ctx, scanner); + yychar = YYEMPTY; + } + } + + /* Else will try to reuse lookahead token after shifting the error + token. */ + goto yyerrlab1; + + + /*---------------------------------------------------. + | yyerrorlab -- error raised explicitly by YYERROR. | + `---------------------------------------------------*/ +yyerrorlab: + + /* Pacify compilers like GCC when the user code never invokes + YYERROR and the label yyerrorlab therefore never appears in user + code. */ + if (/*CONSTCOND*/ 0) + goto yyerrorlab; + + yyerror_range[1] = yylsp[1-yylen]; + /* Do not reclaim the symbols of the rule which action triggered + this YYERROR. */ + YYPOPSTACK (yylen); + yylen = 0; + YY_STACK_PRINT (yyss, yyssp); + yystate = *yyssp; + goto yyerrlab1; + + + /*-------------------------------------------------------------. + | yyerrlab1 -- common code for both syntax error and YYERROR. | + `-------------------------------------------------------------*/ +yyerrlab1: + yyerrstatus = 3; /* Each real token shifted decrements this. */ + + for (;;) { + yyn = yypact[yystate]; + if (!yypact_value_is_default (yyn)) { + yyn += YYTERROR; + if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR) { + yyn = yytable[yyn]; + if (0 < yyn) + break; + } + } + + /* Pop the current state because it cannot handle the error token. */ + if (yyssp == yyss) + YYABORT; + + yyerror_range[1] = *yylsp; + yydestruct ("Error: popping", + yystos[yystate], yyvsp, yylsp, ctx, scanner); + YYPOPSTACK (1); + yystate = *yyssp; + YY_STACK_PRINT (yyss, yyssp); + } + + YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN + *++yyvsp = yylval; + YY_IGNORE_MAYBE_UNINITIALIZED_END + + yyerror_range[2] = yylloc; + /* Using YYLLOC is tempting, but would change the location of + the lookahead. YYLOC is available though. */ + YYLLOC_DEFAULT (yyloc, yyerror_range, 2); + *++yylsp = yyloc; + + /* Shift the error token. */ + YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp); + + yystate = yyn; + goto yynewstate; + + + /*-------------------------------------. + | yyacceptlab -- YYACCEPT comes here. | + `-------------------------------------*/ +yyacceptlab: + yyresult = 0; + goto yyreturn; + + /*-----------------------------------. + | yyabortlab -- YYABORT comes here. | + `-----------------------------------*/ +yyabortlab: + yyresult = 1; + goto yyreturn; + +#if !defined yyoverflow || YYERROR_VERBOSE + /*-------------------------------------------------. + | yyexhaustedlab -- memory exhaustion comes here. | + `-------------------------------------------------*/ +yyexhaustedlab: + yyerror (&yylloc, ctx, scanner, YY_("memory exhausted")); + yyresult = 2; + /* Fall through. */ +#endif + +yyreturn: + if (yychar != YYEMPTY) { + /* Make sure we have latest lookahead translation. See comments at + user semantic actions for why this is necessary. */ + yytoken = YYTRANSLATE (yychar); + yydestruct ("Cleanup: discarding lookahead", + yytoken, &yylval, &yylloc, ctx, scanner); + } + /* Do not reclaim the symbols of the rule which action triggered + this YYABORT or YYACCEPT. */ + YYPOPSTACK (yylen); + YY_STACK_PRINT (yyss, yyssp); + while (yyssp != yyss) { + yydestruct ("Cleanup: popping", + yystos[*yyssp], yyvsp, yylsp, ctx, scanner); + YYPOPSTACK (1); + } +#ifndef yyoverflow + if (yyss != yyssa) + YYSTACK_FREE (yyss); +#endif +#if YYERROR_VERBOSE + if (yymsg != yymsgbuf) + YYSTACK_FREE (yymsg); +#endif + /* Make sure YYID is used. */ + return YYID (yyresult); +} + + +/* Line 2050 of yacc.c */ +#line 253 "promela.ypp" + + diff --git a/src/uscxml/plugins/datamodel/promela/parser/promela.tab.hpp b/src/uscxml/plugins/datamodel/promela/parser/promela.tab.hpp new file mode 100644 index 0000000..a48031a --- /dev/null +++ b/src/uscxml/plugins/datamodel/promela/parser/promela.tab.hpp @@ -0,0 +1,180 @@ +/* A Bison parser, made by GNU Bison 2.7.12-4996. */ + +/* Bison interface for Yacc-like parsers in C + + Copyright (C) 1984, 1989-1990, 2000-2013 Free Software Foundation, Inc. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +/* As a special exception, you may create a larger work that contains + part or all of the Bison parser skeleton and distribute that work + under terms of your choice, so long as that work isn't itself a + parser generator using the skeleton or a modified version thereof + as a parser skeleton. Alternatively, if you modify or redistribute + the parser skeleton itself, you may (at your option) remove this + special exception, which will cause the skeleton and the resulting + Bison output files to be licensed under the GNU General Public + License without this special exception. + + This special exception was added by the Free Software Foundation in + version 2.2 of Bison. */ + +#ifndef YY_PROMELA_PROMELA_TAB_HPP_INCLUDED +# define YY_PROMELA_PROMELA_TAB_HPP_INCLUDED +/* Enabling traces. */ +#ifndef PROMELA_DEBUG +# if defined YYDEBUG +# if YYDEBUG +# define PROMELA_DEBUG 1 +# else +# define PROMELA_DEBUG 0 +# endif +# else /* ! defined YYDEBUG */ +# define PROMELA_DEBUG 1 +# endif /* ! defined YYDEBUG */ +#endif /* ! defined PROMELA_DEBUG */ +#if PROMELA_DEBUG +extern int promela_debug; +#endif + +/* Tokens. */ +#ifndef PROMELA_TOKENTYPE +# define PROMELA_TOKENTYPE + /* Put the tokens into the symbol table, so that GDB and other debuggers + know about them. */ + enum promela_tokentype { + PML_VAR_ARRAY = 258, + PML_VARLIST = 259, + PML_DECL = 260, + PML_DECLLIST = 261, + PML_STMNT = 262, + PML_COLON = 263, + PML_EXPR = 264, + PML_NAMELIST = 265, + PML_ASSERT = 266, + PML_PRINT = 267, + PML_PRINTM = 268, + PML_LEN = 269, + PML_STRING = 270, + PML_TYPEDEF = 271, + PML_MTYPE = 272, + PML_INLINE = 273, + PML_RETURN = 274, + PML_LABEL = 275, + PML_OF = 276, + PML_GOTO = 277, + PML_BREAK = 278, + PML_ELSE = 279, + PML_SEMI = 280, + PML_ARROW = 281, + PML_IF = 282, + PML_FI = 283, + PML_DO = 284, + PML_OD = 285, + PML_FOR = 286, + PML_SELECT = 287, + PML_IN = 288, + PML_SEP = 289, + PML_DOTDOT = 290, + PML_HIDDEN = 291, + PML_SHOW = 292, + PML_ISLOCAL = 293, + PML_CONST = 294, + PML_TYPE = 295, + PML_XU = 296, + PML_NAME = 297, + PML_UNAME = 298, + PML_PNAME = 299, + PML_INAME = 300, + PML_CLAIM = 301, + PML_TRACE = 302, + PML_INIT = 303, + PML_LTL = 304, + PML_COMMA = 305, + PML_ASGN = 306, + PML_AND = 307, + PML_OR = 308, + PML_BITAND = 309, + PML_BITXOR = 310, + PML_BITOR = 311, + PML_NE = 312, + PML_EQ = 313, + PML_LE = 314, + PML_GE = 315, + PML_LT = 316, + PML_GT = 317, + PML_RSHIFT = 318, + PML_LSHIFT = 319, + PML_MINUS = 320, + PML_PLUS = 321, + PML_MODULO = 322, + PML_DIVIDE = 323, + PML_TIMES = 324, + PML_DECR = 325, + PML_INCR = 326, + PML_COMPL = 327, + PML_NEG = 328, + PML_CMPND = 329, + PML_DOT = 330 + }; +#endif + + +#if ! defined PROMELA_STYPE && ! defined PROMELA_STYPE_IS_DECLARED +typedef union PROMELA_STYPE +{ +/* Line 2053 of yacc.c */ +#line 39 "promela.ypp" + + uscxml::PromelaParserNode* node; + char* value; + + +/* Line 2053 of yacc.c */ +#line 146 "promela.tab.hpp" +} PROMELA_STYPE; +# define PROMELA_STYPE_IS_TRIVIAL 1 +# define promela_stype PROMELA_STYPE /* obsolescent; will be withdrawn */ +# define PROMELA_STYPE_IS_DECLARED 1 +#endif + +#if ! defined PROMELA_LTYPE && ! defined PROMELA_LTYPE_IS_DECLARED +typedef struct PROMELA_LTYPE +{ + int first_line; + int first_column; + int last_line; + int last_column; +} PROMELA_LTYPE; +# define promela_ltype PROMELA_LTYPE /* obsolescent; will be withdrawn */ +# define PROMELA_LTYPE_IS_DECLARED 1 +# define PROMELA_LTYPE_IS_TRIVIAL 1 +#endif + + +#ifdef YYPARSE_PARAM +#if defined __STDC__ || defined __cplusplus +int promela_parse (void *YYPARSE_PARAM); +#else +int promela_parse (); +#endif +#else /* ! YYPARSE_PARAM */ +#if defined __STDC__ || defined __cplusplus +int promela_parse (uscxml::PromelaParser* ctx, void * scanner); +#else +int promela_parse (); +#endif +#endif /* ! YYPARSE_PARAM */ + +#endif /* !YY_PROMELA_PROMELA_TAB_HPP_INCLUDED */ diff --git a/src/uscxml/plugins/datamodel/promela/parser/promela.ypp b/src/uscxml/plugins/datamodel/promela/parser/promela.ypp new file mode 100644 index 0000000..d76b24a --- /dev/null +++ b/src/uscxml/plugins/datamodel/promela/parser/promela.ypp @@ -0,0 +1,254 @@ +/** Subset extracted from spin.y by Stefan Radomski 2014 */ + +/***** spin: spin.y *****/ + +/* Copyright (c) 1989-2003 by Lucent Technologies, Bell Laboratories. */ +/* All Rights Reserved. This software is for educational purposes only. */ +/* No guarantee whatsoever is expressed or implied by the distribution of */ +/* this code. Permission is given to distribute this code provided that */ +/* this introductory message is not removed and no monies are exchanged. */ +/* Software written by Gerard J. Holzmann. For tool documentation see: */ +/* http://spinroot.com/ */ +/* Send all bug-reports and/or questions to: bugs@spinroot.com */ + +%{ +#include "../PromelaParser.h" +#include "promela.tab.hpp" +#include +#include + +#define YYMAXDEPTH 20000 // default is 10000 +#define YYDEBUG 1 +#define YYERROR_VERBOSE 1 + +extern int promela_lex (PROMELA_STYPE* yylval_param, PROMELA_LTYPE* yylloc_param, void* yyscanner); + +using namespace uscxml; +%} + +%pure-parser +%debug +%locations +%file-prefix "promela" +%parse-param { uscxml::PromelaParser* ctx } +%lex-param {void * scanner} +%parse-param {void * scanner} +%define api.prefix promela_ +%defines + +%union { + uscxml::PromelaParserNode* node; + char* value; +} + +%error-verbose + +/* %type expr_lst */ +%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 + +%token '(' ')' +%token '[' ']' +%token '{' '}' +%token PML_ASSERT PML_PRINT PML_PRINTM +%token PML_LEN PML_STRING +%token PML_TYPEDEF PML_MTYPE PML_INLINE PML_RETURN PML_LABEL PML_OF +%token PML_GOTO PML_BREAK PML_ELSE PML_SEMI PML_ARROW +%token PML_IF PML_FI PML_DO PML_OD PML_FOR PML_SELECT PML_IN PML_SEP PML_DOTDOT +%token PML_HIDDEN PML_SHOW PML_ISLOCAL +%token PML_CONST PML_TYPE PML_XU /* val */ +%token PML_NAME PML_UNAME PML_PNAME PML_INAME /* sym */ +%token PML_CLAIM PML_TRACE PML_INIT PML_LTL /* sym */ +%token PML_COMMA + +%right PML_ASGN +%left PML_OR PML_AND +%left PML_BITOR PML_BITXOR PML_BITAND +%left PML_EQ PML_NE +%left PML_GT PML_LT PML_GE PML_LE +%left PML_LSHIFT PML_RSHIFT +%left PML_PLUS PML_MINUS +%left PML_TIMES PML_DIVIDE PML_MODULO +%left PML_INCR PML_DECR +%left PML_COMPL +%right PML_NEG +%left PML_DOT PML_CMPND + +%% + + +/** PROMELA Grammar Rules **/ + +program : + decl_lst { + ctx->ast = $1; + ctx->type = PromelaParser::PROMELA_DECL; + } + | expr { + ctx->ast = $1; + ctx->type = PromelaParser::PROMELA_EXPR; + } + | stmnt_lst { + ctx->ast = $1; + ctx->type = PromelaParser::PROMELA_STMNT; + } + ; + +varref : cmpnd { $$ = $1; } + ; + +pfld : PML_NAME { $$ = ctx->value(PML_NAME, (void*)&(@1), $1); free($1); } + | PML_NAME '[' expr ']' { $$ = ctx->node(PML_VAR_ARRAY, 2, ctx->value(PML_NAME, (void*)&(@1), $1), $3); free($1); } + ; + +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 */ { $$ = NULL; } + | PML_DOT cmpnd %prec PML_DOT { $$ = $2; } + ; + +/* +expr_lst: expr { $$ = ctx->node(PML_EXPR, 1, $1); } + | expr PML_SEMI { $$ = ctx->node(PML_EXPR, 1, $1); } + | expr PML_SEMI expr_lst { $$ = ctx->node(PML_EXPR, 2, $1, $3); } + ; +*/ + +expr : '(' expr ')' { $$ = $2; } + | expr PML_PLUS expr { $$ = ctx->node(PML_PLUS, 2, $1, $3); } + | expr PML_MINUS expr { $$ = ctx->node(PML_MINUS, 2, $1, $3); } + | expr PML_TIMES expr { $$ = ctx->node(PML_TIMES, 2, $1, $3); } + | expr PML_DIVIDE expr { $$ = ctx->node(PML_DIVIDE, 2, $1, $3); } + | expr PML_MODULO expr { $$ = ctx->node(PML_MODULO, 2, $1, $3); } + | expr PML_BITAND expr { $$ = ctx->node(PML_BITAND, 2, $1, $3); } + | expr PML_BITXOR expr { $$ = ctx->node(PML_BITXOR, 2, $1, $3); } + | expr PML_BITOR expr { $$ = ctx->node(PML_BITOR, 2, $1, $3); } + | expr PML_GT expr { $$ = ctx->node(PML_GT, 2, $1, $3); } + | expr PML_LT expr { $$ = ctx->node(PML_LT, 2, $1, $3); } + | expr PML_GE expr { $$ = ctx->node(PML_GE, 2, $1, $3); } + | expr PML_LE expr { $$ = ctx->node(PML_LE, 2, $1, $3); } + | expr PML_EQ expr { $$ = ctx->node(PML_EQ, 2, $1, $3); } + | expr PML_NE expr { $$ = ctx->node(PML_NE, 2, $1, $3); } + | expr PML_AND expr { $$ = ctx->node(PML_AND, 2, $1, $3); } + | expr PML_OR expr { $$ = ctx->node(PML_OR, 2, $1, $3); } + | expr PML_LSHIFT expr { $$ = ctx->node(PML_LSHIFT, 2, $1, $3); } + | expr PML_RSHIFT expr { $$ = ctx->node(PML_RSHIFT, 2, $1, $3); } + | PML_NEG expr { $$ = ctx->node(PML_NEG, 1, $2); } + | PML_MINUS expr %prec PML_MINUS { $$ = ctx->node(PML_MINUS, 1, $2); } + + | PML_LEN '(' varref ')' { $$ = ctx->node(PML_LEN, 1, $3); } + | varref { $$ = $1; } + | PML_CONST { $$ = ctx->value(PML_CONST, (void*)&(@1), $1); free($1); } + | PML_STRING { + /* Non standard promela for string literals */ + $$ = ctx->value(PML_STRING, (void*)&(@1), $1); free($1); } + ; + + +vis : /* empty */ { $$ = ctx->node(PML_SHOW, 0); } + | PML_HIDDEN { $$ = ctx->node(PML_HIDDEN, 0); } + | PML_SHOW { $$ = ctx->node(PML_SHOW, 0); } + | PML_ISLOCAL { $$ = ctx->node(PML_ISLOCAL, 0); } + ; + +one_decl: vis PML_TYPE var_list { $$ = ctx->node(PML_DECL, 3, $1, ctx->value(PML_TYPE, (void*)&(@2), $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, (void*)&(@2), $2), $5); free($2); } + | vis utype { $$ = $2; } + ; + +utype : PML_TYPEDEF PML_NAME '{' decl_lst '}' { $$ = ctx->node(PML_TYPEDEF, 2, ctx->value(PML_NAME, (void*)&(@2), $2), $4); } + ; + +decl_lst: one_decl { $$ = $1; } + | one_decl PML_SEMI { $$ = $1; } + | one_decl PML_SEMI decl_lst { + $$ = ctx->node(PML_DECLLIST, 1, $1); + if($3->type == PML_DECLLIST) { + $$->merge($3); delete $3; + } else { + $$->push($3); + } + } + ; + +var_list: ivar { $$ = ctx->node(PML_VARLIST, 1, $1); } + | ivar PML_COMMA var_list { $$ = ctx->node(PML_VARLIST, 1, $1); $$->merge($3); delete $3; } + ; + +ivar : vardcl { $$ = $1; } + | vardcl PML_ASGN expr { $$ = ctx->node(PML_ASGN, 2, $1, $3); } + ; + +vardcl : PML_NAME { $$ = ctx->value(PML_NAME, (void*)&(@1), $1); free($1); } + | PML_NAME PML_COLON PML_CONST { $$ = ctx->node(PML_COLON, 2, ctx->value(PML_NAME, (void*)&(@1), $1), ctx->value(PML_CONST, (void*)&(@3), $3)); free($1); free($3); } + | PML_NAME '[' const_expr ']' { $$ = ctx->node(PML_VAR_ARRAY, 2, ctx->value(PML_NAME, (void*)&(@1), $1), $3); free($1); } + ; + +const_expr: PML_CONST { $$ = ctx->value(PML_CONST, (void*)&(@1), $1); free($1); } + | PML_MINUS const_expr %prec PML_MINUS { $$ = ctx->node(PML_MINUS, 1, $2); } + | '(' const_expr ')' { $$ = $2; } + | const_expr PML_PLUS const_expr { $$ = ctx->node(PML_PLUS, 2, $1, $3); } + | const_expr PML_MINUS const_expr { $$ = ctx->node(PML_MINUS, 2, $1, $3); } + | const_expr PML_TIMES const_expr { $$ = ctx->node(PML_TIMES, 2, $1, $3); } + | const_expr PML_DIVIDE const_expr { $$ = ctx->node(PML_DIVIDE, 2, $1, $3); } + | const_expr PML_MODULO const_expr { $$ = ctx->node(PML_MODULO, 2, $1, $3); } + ; + +nlst : PML_NAME { $$ = ctx->value(PML_NAME, (void*)&(@1), $1); free($1); } + | nlst PML_NAME { + if ($1->type == PML_NAME) { + $$ = ctx->node(PML_NAMELIST, 1, $1); + $$->push(ctx->value(PML_NAME, (void*)&(@2), $2)); + } else { + $1->push(ctx->value(PML_NAME, (void*)&(@2), $2)); + } + free($2); + } + | nlst PML_COMMA { $$ = $1; } + ; + +stmnt_lst: stmnt { $$ = $1; } + | stmnt PML_SEMI { $$ = $1; } + | stmnt PML_SEMI stmnt_lst { $$ = ctx->node(PML_STMNT, 2, $1, $3); } + ; + +stmnt : Stmnt { $$ = $1; } + ; + +Stmnt : varref PML_ASGN expr { $$ = ctx->node(PML_ASGN, 2, $1, $3); } + | varref PML_INCR { $$ = ctx->node(PML_INCR, 1, $1); } + | varref PML_DECR { $$ = ctx->node(PML_DECR, 1, $1); } + | PML_PRINT '(' PML_STRING prargs ')' { $$ = ctx->node(PML_PRINT, 2, ctx->value(PML_STRING, (void*)&(@3), $3), $4); free($3); } + | PML_PRINT '(' varref ')' { $$ = ctx->node(PML_PRINT, 1, $3); } + | PML_PRINT '(' PML_CONST ')' { $$ = ctx->node(PML_PRINT, 1, ctx->value(PML_CONST, (void*)&(@3), $3)); free($3); } + | PML_ASSERT expr { $$ = ctx->node(PML_ASSERT, 1, $2); } + | expr { $$ = $1; } + ; + +prargs : /* empty */ { $$ = ctx->value(0, NULL, ""); } + | PML_COMMA arg { $$ = $2; } + ; + +arg : expr { $$ = $1; } + | expr PML_COMMA arg { $$ = ctx->node(0, 2, $1, $3); } + ; + + +%% + diff --git a/src/uscxml/plugins/invoker/dirmon/DirMonInvoker.cpp b/src/uscxml/plugins/invoker/dirmon/DirMonInvoker.cpp index f3b429f..08a0be8 100644 --- a/src/uscxml/plugins/invoker/dirmon/DirMonInvoker.cpp +++ b/src/uscxml/plugins/invoker/dirmon/DirMonInvoker.cpp @@ -134,8 +134,8 @@ void DirMonInvoker::invoke(const std::string& source, const Event& req) { std::multimap::const_iterator dirIter = req.params.find("dir"); while(dirIter != req.params.upper_bound("dir")) { // this is simplified - Data might be more elaborate than a simple string atom - URL url = URL::resolve(dirIter->second.atom, _interpreter->getBaseURL()); - + URL url = URL::resolve(dirIter->second.atom, _interpreter->getBaseURL()); + if (!url.isAbsolute()) { LOG(ERROR) << "Given directory '" << dirIter->second << "' cannot be transformed to absolute path"; } else { @@ -153,13 +153,13 @@ void DirMonInvoker::invoke(const std::string& source, const Event& req) { } void DirMonInvoker::uninvoke() { - _isRunning = false; - if (_thread) { - _thread->join(); - delete _thread; - } + _isRunning = false; + if (_thread) { + _thread->join(); + delete _thread; + } } - + void DirMonInvoker::run(void* instance) { while(((DirMonInvoker*)instance)->_isRunning) { { diff --git a/src/uscxml/plugins/invoker/dirmon/DirMonInvoker.h b/src/uscxml/plugins/invoker/dirmon/DirMonInvoker.h index be510d9..6e13864 100644 --- a/src/uscxml/plugins/invoker/dirmon/DirMonInvoker.h +++ b/src/uscxml/plugins/invoker/dirmon/DirMonInvoker.h @@ -107,9 +107,9 @@ public: } virtual Data getDataModelVariables(); - virtual void eventFromSCXML(const Event& event); - virtual void invoke(const std::string& source, const Event& invokeEvent); - virtual void uninvoke(); + virtual void eventFromSCXML(const Event& event); + virtual void invoke(const std::string& source, const Event& invokeEvent); + virtual void uninvoke(); virtual void handleChanges(DirectoryWatch::Action action, const std::string dir, const std::string file, struct stat fileStat); diff --git a/src/uscxml/plugins/ioprocessor/basichttp/BasicHTTPIOProcessor.cpp b/src/uscxml/plugins/ioprocessor/basichttp/BasicHTTPIOProcessor.cpp index 317b94c..564977d 100644 --- a/src/uscxml/plugins/ioprocessor/basichttp/BasicHTTPIOProcessor.cpp +++ b/src/uscxml/plugins/ioprocessor/basichttp/BasicHTTPIOProcessor.cpp @@ -200,8 +200,8 @@ void BasicHTTPIOProcessor::eventFromSCXML(const std::string& target, const Event kvps << kvpSeperator << eventNameCStr << "=" << eventValueCStr; kvpSeperator = "&"; targetURL.addOutHeader("_scxmleventname", eventValueCStr); - free(eventNameCStr); - free(eventValueCStr); + free(eventNameCStr); + free(eventValueCStr); } // event namelist diff --git a/src/uscxml/server/HTTPServer.cpp b/src/uscxml/server/HTTPServer.cpp index 071846c..679ab67 100644 --- a/src/uscxml/server/HTTPServer.cpp +++ b/src/uscxml/server/HTTPServer.cpp @@ -386,14 +386,14 @@ void HTTPServer::httpRecvReqCallback(struct evhttp_request *req, void *callbackD key = item.substr(0, equalPos); value = item.substr(equalPos + 1, item.length() - (equalPos + 1)); - size_t keyCStrLen = 0; - size_t valueCStrLen = 0; - char* keyCStr = evhttp_uridecode(key.c_str(), 1, &keyCStrLen); + size_t keyCStrLen = 0; + size_t valueCStrLen = 0; + char* keyCStr = evhttp_uridecode(key.c_str(), 1, &keyCStrLen); char* valueCStr = evhttp_uridecode(value.c_str(), 1, &valueCStrLen); - std::string decKey = std::string(keyCStr, keyCStrLen); - std::string decValue = std::string(valueCStr, valueCStrLen); - - request.data.compound["content"].compound[decKey] = Data(decValue, Data::VERBATIM); + std::string decKey = std::string(keyCStr, keyCStrLen); + std::string decValue = std::string(valueCStr, valueCStrLen); + + request.data.compound["content"].compound[decKey] = Data(decValue, Data::VERBATIM); free(keyCStr); free(valueCStr); key.clear(); @@ -418,11 +418,11 @@ void HTTPServer::httpRecvReqCallback(struct evhttp_request *req, void *callbackD request.raw = raw.str(); #if 0 - std::cout << "====" << std::endl; - std::cout << request.raw << std::endl; - std::cout << "====" << std::endl; + std::cout << "====" << std::endl; + std::cout << request.raw << std::endl; + std::cout << "====" << std::endl; #endif - + // try with the handler registered for path first bool answered = false; if (callbackData != NULL) diff --git a/src/uscxml/transform/ChartToC.cpp b/src/uscxml/transform/ChartToC.cpp index 04f0378..10eee0c 100644 --- a/src/uscxml/transform/ChartToC.cpp +++ b/src/uscxml/transform/ChartToC.cpp @@ -50,7 +50,7 @@ ChartToC::ChartToC(const Interpreter& other) : TransformerImpl(other), _topMostM ss << _document; _md5 = md5(ss.str()); - _prefix = "_uscxml_" + _md5.substr(0, 8); + _prefix = "_uscxml_" + _md5.substr(0, 8) + "_"; _allMachines.push_back(this); prepare(); @@ -1189,7 +1189,7 @@ void ChartToC::writeExecContent(std::ostream& stream) { } -void ChartToC::writeExecContent(std::ostream& stream, const DOMNode* node, int indent) { +void ChartToC::writeExecContent(std::ostream& stream, const DOMNode* node, size_t indent) { if (!node) return; @@ -2560,4 +2560,4 @@ void ChartToC::writeFSM(std::ostream& stream) { ChartToC::~ChartToC() { } -} \ No newline at end of file +} diff --git a/src/uscxml/transform/ChartToC.h b/src/uscxml/transform/ChartToC.h index 43ffc45..9fe6a9f 100644 --- a/src/uscxml/transform/ChartToC.h +++ b/src/uscxml/transform/ChartToC.h @@ -58,7 +58,7 @@ protected: void writeFSM(std::ostream& stream); void writeCharArrayInitList(std::ostream& stream, const std::string& boolString); - void writeExecContent(std::ostream& stream, const XERCESC_NS::DOMNode* node, int indent = 0); + void writeExecContent(std::ostream& stream, const XERCESC_NS::DOMNode* node, size_t indent = 0); void resortStates(XERCESC_NS::DOMNode* node); void setHistoryCompletion(); diff --git a/src/uscxml/transform/ChartToPromela.cpp b/src/uscxml/transform/ChartToPromela.cpp new file mode 100644 index 0000000..a697d99 --- /dev/null +++ b/src/uscxml/transform/ChartToPromela.cpp @@ -0,0 +1,2625 @@ +/** + * @file + * @author 2012-2014 Stefan Radomski (stefan.radomski@cs.tu-darmstadt.de) + * @copyright Simplified BSD + * + * @cond + * This program is free software: you can redistribute it and/or modify + * it under the terms of the FreeBSD license as published by the FreeBSD + * project. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * You should have received a copy of the FreeBSD license along with this + * program. If not, see . + * @endcond + */ + +#include "uscxml/transform/ChartToPromela.h" +#include "uscxml/util/Predicates.h" +#include "uscxml/util/String.h" +#include "uscxml/plugins/datamodel/promela/PromelaParser.h" +#include "uscxml/plugins/datamodel/promela/parser/promela.tab.hpp" + +#include +#include + +#include + +#define ADAPT_SRC(code) _analyzer.adaptCode(code, _prefix) +#define BIT_WIDTH(number) (number > 1 ? (int)ceil(log((double)number) / log((double)2.0)) : 1) +#define EVENT_NAME (_analyzer.usesComplexEventStruct() ? "_event.name" : "_event") + +namespace uscxml { + +using namespace XERCESC_NS; + + +Transformer ChartToPromela::transform(const Interpreter& other) { + return std::shared_ptr(new ChartToPromela(other)); +} + +ChartToPromela::~ChartToPromela() { +} + +/** + The following tests FAILED: + 1740 - w3c/spin/promela/test150.scxml (Failed) + 1741 - w3c/spin/promela/test151.scxml (Failed) + 1742 - w3c/spin/promela/test152.scxml (Failed) + 1743 - w3c/spin/promela/test153.scxml (Failed) + 1744 - w3c/spin/promela/test155.scxml (Failed) + 1745 - w3c/spin/promela/test156.scxml (Failed) + 1749 - w3c/spin/promela/test173.scxml (Failed) + 1750 - w3c/spin/promela/test174.scxml (Failed) + 1752 - w3c/spin/promela/test176.scxml (Failed) + 1753 - w3c/spin/promela/test178.scxml (Failed) + 1754 - w3c/spin/promela/test179.scxml (Failed) + 1757 - w3c/spin/promela/test186.scxml (Failed) + 1762 - w3c/spin/promela/test192.scxml (Failed) + 1763 - w3c/spin/promela/test193.scxml (Failed) + 1765 - w3c/spin/promela/test198.scxml (Failed) + 1769 - w3c/spin/promela/test205.scxml (Failed) + 1770 - w3c/spin/promela/test207.scxml (Failed) + 1771 - w3c/spin/promela/test208.scxml (Failed) + 1772 - w3c/spin/promela/test210.scxml (Failed) + 1773 - w3c/spin/promela/test215.scxml (Failed) + 1774 - w3c/spin/promela/test216.scxml (Failed) + 1776 - w3c/spin/promela/test223.scxml (Failed) + 1777 - w3c/spin/promela/test224.scxml (Failed) + 1778 - w3c/spin/promela/test225.scxml (Failed) + 1780 - w3c/spin/promela/test228.scxml (Failed) + 1782 - w3c/spin/promela/test230.scxml (Failed) + 1783 - w3c/spin/promela/test232.scxml (Failed) + 1785 - w3c/spin/promela/test234.scxml (Failed) + 1787 - w3c/spin/promela/test236.scxml (Failed) + 1788 - w3c/spin/promela/test237.scxml (Failed) + 1789 - w3c/spin/promela/test239.scxml (Failed) + 1790 - w3c/spin/promela/test240.scxml (Failed) + 1791 - w3c/spin/promela/test241.scxml (Failed) + 1792 - w3c/spin/promela/test242.scxml (Failed) + 1797 - w3c/spin/promela/test250.scxml (Failed) + 1798 - w3c/spin/promela/test252.scxml (Failed) + 1799 - w3c/spin/promela/test253.scxml (Failed) + 1802 - w3c/spin/promela/test278.scxml (Failed) + 1803 - w3c/spin/promela/test279.scxml (Failed) + 1805 - w3c/spin/promela/test286.scxml (Failed) + 1808 - w3c/spin/promela/test294.scxml (Failed) + 1809 - w3c/spin/promela/test298.scxml (Failed) + 1811 - w3c/spin/promela/test302.scxml (Failed) + 1813 - w3c/spin/promela/test304.scxml (Failed) + 1814 - w3c/spin/promela/test309.scxml (Failed) + 1815 - w3c/spin/promela/test310.scxml (Failed) + 1816 - w3c/spin/promela/test311.scxml (Failed) + 1817 - w3c/spin/promela/test312.scxml (Failed) + 1818 - w3c/spin/promela/test313.scxml (Failed) + 1819 - w3c/spin/promela/test314.scxml (Failed) + 1820 - w3c/spin/promela/test318.scxml (Failed) + 1823 - w3c/spin/promela/test322.scxml (Failed) + 1825 - w3c/spin/promela/test324.scxml (Failed) + 1827 - w3c/spin/promela/test326.scxml (Failed) + 1828 - w3c/spin/promela/test329.scxml (Failed) + 1829 - w3c/spin/promela/test330.scxml (Failed) + 1830 - w3c/spin/promela/test331.scxml (Failed) + 1831 - w3c/spin/promela/test332.scxml (Failed) + 1832 - w3c/spin/promela/test333.scxml (Failed) + 1833 - w3c/spin/promela/test335.scxml (Failed) + 1835 - w3c/spin/promela/test337.scxml (Failed) + 1837 - w3c/spin/promela/test339.scxml (Failed) + 1838 - w3c/spin/promela/test342.scxml (Failed) + 1839 - w3c/spin/promela/test343.scxml (Failed) + 1840 - w3c/spin/promela/test344.scxml (Failed) + 1841 - w3c/spin/promela/test346.scxml (Failed) + 1842 - w3c/spin/promela/test347.scxml (Failed) + 1846 - w3c/spin/promela/test351.scxml (Failed) + 1847 - w3c/spin/promela/test352.scxml (Failed) + 1848 - w3c/spin/promela/test354.scxml (Failed) + 1849 - w3c/spin/promela/test355.scxml (Failed) + 1850 - w3c/spin/promela/test364.scxml (Failed) + 1851 - w3c/spin/promela/test372.scxml (Failed) + 1854 - w3c/spin/promela/test377.scxml (Failed) + 1855 - w3c/spin/promela/test378.scxml (Failed) + 1856 - w3c/spin/promela/test387.scxml (Failed) + 1857 - w3c/spin/promela/test388.scxml (Failed) + 1858 - w3c/spin/promela/test396.scxml (Failed) + 1859 - w3c/spin/promela/test399.scxml (Failed) + 1860 - w3c/spin/promela/test401.scxml (Failed) + 1861 - w3c/spin/promela/test402.scxml (Failed) + 1862 - w3c/spin/promela/test403a.scxml (Failed) + 1863 - w3c/spin/promela/test403b.scxml (Failed) + 1864 - w3c/spin/promela/test403c.scxml (Failed) + 1865 - w3c/spin/promela/test404.scxml (Failed) + 1866 - w3c/spin/promela/test405.scxml (Failed) + 1867 - w3c/spin/promela/test406.scxml (Failed) + 1868 - w3c/spin/promela/test407.scxml (Failed) + 1869 - w3c/spin/promela/test409.scxml (Failed) + 1870 - w3c/spin/promela/test411.scxml (Failed) + 1871 - w3c/spin/promela/test412.scxml (Failed) + 1872 - w3c/spin/promela/test413.scxml (Failed) + 1873 - w3c/spin/promela/test415.scxml (Failed) + 1874 - w3c/spin/promela/test416.scxml (Failed) + 1875 - w3c/spin/promela/test417.scxml (Failed) + 1877 - w3c/spin/promela/test421.scxml (Failed) + 1878 - w3c/spin/promela/test422.scxml (Failed) + 1880 - w3c/spin/promela/test487.scxml (Failed) + 1881 - w3c/spin/promela/test488.scxml (Failed) + 1882 - w3c/spin/promela/test495.scxml (Failed) + 1886 - w3c/spin/promela/test503.scxml (Failed) + 1887 - w3c/spin/promela/test504.scxml (Failed) + 1888 - w3c/spin/promela/test505.scxml (Failed) + 1890 - w3c/spin/promela/test509.scxml (Failed) + 1892 - w3c/spin/promela/test518.scxml (Failed) + 1893 - w3c/spin/promela/test519.scxml (Failed) + 1894 - w3c/spin/promela/test520.scxml (Failed) + 1897 - w3c/spin/promela/test525.scxml (Failed) + 1898 - w3c/spin/promela/test527.scxml (Failed) + 1899 - w3c/spin/promela/test528.scxml (Failed) + 1900 - w3c/spin/promela/test529.scxml (Failed) + 1901 - w3c/spin/promela/test530.scxml (Failed) + 1902 - w3c/spin/promela/test531.scxml (Failed) + 1903 - w3c/spin/promela/test532.scxml (Failed) + 1904 - w3c/spin/promela/test533.scxml (Failed) + 1905 - w3c/spin/promela/test534.scxml (Failed) + 1906 - w3c/spin/promela/test550.scxml (Failed) + 1907 - w3c/spin/promela/test551.scxml (Failed) + 1911 - w3c/spin/promela/test567.scxml (Failed) + 1912 - w3c/spin/promela/test570.scxml (Failed) + 1913 - w3c/spin/promela/test576.scxml (Failed) + 1915 - w3c/spin/promela/test579.scxml (Failed) + 1916 - w3c/spin/promela/test580.scxml (Failed) +*/ + +void ChartToPromela::prepare() { + if (_machinesAll == NULL) { + _machinesAll = new std::map(); + (*_machinesAll)[_scxml] = this; + } + + if (_machinesAllPerId == NULL) + _machinesAllPerId = new std::map(); + + if (_parentTopMost == NULL) + _parentTopMost = this; + + // transform data / assign json into PROMELA statements + std::list values; + + values.splice(values.end(), DOMUtils::inDocumentOrder({XML_PREFIX(_scxml).str() + "assign"}, _scxml)); + values.splice(values.end(), DOMUtils::inDocumentOrder({XML_PREFIX(_scxml).str() + "data"}, _scxml)); + + for (auto element : values) { + std::string key; + if (HAS_ATTR(element, "id")) { + key = ATTR(element, "id"); + } else if (HAS_ATTR(element, "location")) { + key = ATTR(element, "location"); + } + + if (key.length() == 0) + continue; + + std::string value; + if (HAS_ATTR(element, "expr")) { + value = ATTR(element, "expr"); + } else if (HAS_ATTR(element, "src")) { + URL absUrl = URL::resolve(ATTR_CAST(element, "src"), _baseURL); + value = absUrl.getInContent(); + } else { + std::list assignTexts = DOMUtils::filterChildType(DOMNode::TEXT_NODE, element, true); + if (assignTexts.size() > 0) { + for (auto assignText : assignTexts) { + value += X(assignText->getNodeValue()).str(); + } + } + } + + boost::trim(value); + if (value.size() == 0) + continue; + + // remove all children, we will replae by suitable promela statements + while(element->hasChildNodes()) + element->removeChild(element->getFirstChild()); + + std::string newValue; + Data json = Data::fromJSON(value); + if (!json.empty()) { + newValue = dataToAssignments(key, json); + } else { + newValue = key + " = " + value + ";"; + } + + if (LOCALNAME(element) == "data") + _varInitializers.push_back(newValue); + + DOMText* newText = _document->createTextNode(X(newValue)); + element->insertBefore(newText, NULL); + + _analyzer.addCode(newValue, this); + + } +} + +void ChartToPromela::writeTo(std::ostream& stream) { + + _analyzer.analyze(this); + // same preparations as the C transformation + prepare(); + + stream << "/** generated from " << std::endl; + stream << " " << std::string(_baseURL) << std::endl; + stream << " Use as:" << std::endl; + stream << " $ spin -a this.pml" << std::endl; + stream << " $ gcc pan.c -o pan" << std::endl; + stream << " $ ./pan -a -n -N w3c" << std::endl; + stream << " */" << std::endl; + stream << std::endl; + + + writeMacros(stream); + stream << std::endl; + writeTypeDefs(stream); + stream << std::endl; + writeTypes(stream); + stream << std::endl; + writeStrings(stream); + stream << std::endl; + writeCancelEvents(stream); + stream << std::endl; + writeFSM(stream); + stream << std::endl; + + + stream << "init {" << std::endl; + + stream << "/* initialize state and transition information */" << std::endl; + writeTransitions(stream); + stream << std::endl; + writeStates(stream); + stream << std::endl; + + stream << "/* initialize data model variables */" << std::endl; + stream << " " << _prefix << "flags[USCXML_CTX_PRISTINE] = true;" << std::endl; + stream << " " << _prefix << "flags[USCXML_CTX_SPONTANEOUS] = true;" << std::endl; + + for (auto initializer : _varInitializers) { + stream << ADAPT_SRC(beautifyIndentation(initializer, 1)) << std::endl; + } + + stream << std::endl; + + stream << " run " << _prefix << "step() priority 10;" << std::endl; + stream << "}" << std::endl; + stream << std::endl; + stream << "ltl w3c { eventually (" << _prefix << "config[" << _prefix << "PASS]) }" << std::endl; + +} + +void ChartToPromela::bit_clear_all(std::ostream& stream, + const std::string& identifier, + size_t length, + size_t indent) { + std::string padding; + while (indent--) + padding += " "; + stream << std::endl; + stream << padding << "/** clearing all bits of " << identifier << " */" << std::endl; + for (size_t i = 0; i < length; i++) { + stream << padding << identifier << "[" << i << "] = false;" << std::endl; + } +} + +void ChartToPromela::bit_copy(std::ostream& stream, + const std::string& from, + const std::string& to, + size_t length, + size_t indent) { + std::string padding; + while (indent--) + padding += " "; + stream << std::endl; + stream << padding << "/** copy bits from " << from << " to " << to << " */" << std::endl; + for (size_t i = 0; i < length; i++) { + stream << padding << to << "[" << i << "] = "<< from << "[" << i << "];" << std::endl; + } +} + +void ChartToPromela::bit_or(std::ostream& stream, + const std::string& to, + const std::string& mask, + size_t length, + size_t indent) { + std::string padding; + while (indent--) + padding += " "; + stream << std::endl; + stream << padding << "/** or'ing bits in " << to << " with mask " << mask << " */" << std::endl; + for (size_t i = 0; i < length; i++) { + stream << padding << to << "[" << i << "] = "<< to << "[" << i << "] | " << mask << "[" << i << "];" << std::endl; + } +} + +void ChartToPromela::bit_and(std::ostream& stream, + const std::string& to, + const std::string& mask, + size_t length, + size_t indent) { + std::string padding; + while (indent--) + padding += " "; + stream << std::endl; + stream << padding << "/** and'ing bits in " << to << " with mask " << mask << " */" << std::endl; + for (size_t i = 0; i < length; i++) { + stream << padding << to << "[" << i << "] = "<< to << "[" << i << "] & " << mask << "[" << i << "];" << std::endl; + } +} + +void ChartToPromela::bit_and_not(std::ostream& stream, + const std::string& to, + const std::string& mask, + size_t length, + size_t indent) { + std::string padding; + while (indent--) + padding += " "; + stream << std::endl; + stream << padding << "/** not and'ing bits in " << to << " with mask " << mask << " */" << std::endl; + for (size_t i = 0; i < length; i++) { + stream << padding << to << "[" << i << "] = "<< to << "[" << i << "] & !" << mask << "[" << i << "];" << std::endl; + } +} + +void ChartToPromela::bit_has_and(std::ostream& stream, + const std::string& a, + const std::string& b, + size_t length, + size_t indent) { + std::string padding; + while (indent--) + padding += " "; + stream << "(false /** is there a common bit in " << a << " and " << b << " */" << std::endl; + for (size_t i = 0; i < length; i++) { + stream << padding << " || " << a << "[" << i << "] & "<< b << "[" << i << "]" << std::endl; + } + stream << padding << ")"; + +} + +void ChartToPromela::printBitArray(std::ostream& stream, + const std::string& array, + size_t length, + size_t indent) { + std::string padding; + while (indent--) + padding += " "; + + stream << padding << "printf(\""; + for (size_t i = 0; i < length; i++) { + stream << "%d"; + } + stream << "\", " << std::endl; + for (size_t i = 0; i < length; i++) { + stream << padding << " " << array << "[" << toStr(i) << "]"; + if (i + 1 < length) { + stream << ", " << std::endl; + } + } + stream << ");" << std::endl; +} + +void ChartToPromela::writeMacros(std::ostream& stream) { + stream << "/* machine state flags */" << std::endl; + stream << "#define USCXML_CTX_PRISTINE 0" << std::endl; + stream << "#define USCXML_CTX_SPONTANEOUS 1" << std::endl; + stream << "#define USCXML_CTX_INITIALIZED 2" << std::endl; + stream << "#define USCXML_CTX_TOP_LEVEL_FINAL 3" << std::endl; + stream << "#define USCXML_CTX_TRANSITION_FOUND 4" << std::endl; + stream << "#define USCXML_CTX_FINISHED 5" << std::endl; + stream << std::endl; + + stream << "#define USCXML_TRANS_SPONTANEOUS 0" << std::endl; + stream << "#define USCXML_TRANS_TARGETLESS 1" << std::endl; + stream << "#define USCXML_TRANS_INTERNAL 2" << std::endl; + stream << "#define USCXML_TRANS_HISTORY 3" << std::endl; + stream << "#define USCXML_TRANS_INITIAL 4" << std::endl; + stream << std::endl; + + stream << "#define USCXML_STATE_ATOMIC 0" << std::endl; + stream << "#define USCXML_STATE_PARALLEL 1" << std::endl; + stream << "#define USCXML_STATE_COMPOUND 2" << std::endl; + stream << "#define USCXML_STATE_FINAL 3" << std::endl; + stream << "#define USCXML_STATE_HISTORY_DEEP 4" << std::endl; + stream << "#define USCXML_STATE_HISTORY_SHALLOW 5" << std::endl; + stream << "#define USCXML_STATE_INITIAL 6" << std::endl; + stream << "#define USCXML_STATE_HAS_HISTORY 7" << std::endl; + stream << std::endl; + + stream << "#define USCXML_ERR_OK 0" << std::endl; + stream << "#define USCXML_ERR_DONE 1" << std::endl; + stream << std::endl; + + stream << "#define USCXML_EVENT_SPONTANEOUS 0" << std::endl; + stream << std::endl; + stream << "#define TRACE_EXECUTION 1" << std::endl; + stream << std::endl; + + +} + +void ChartToPromela::writeTypeDefs(std::ostream& stream) { + stream << "/* type definitions */" << 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; + + stream << "typedef " << currDef.name << " {" << std::endl; + if (currDef.name.compare("_event_t") ==0) { + if (_analyzer.usesEventField("delay")) { + // make sure delay is the first member for sorted enqueuing to work + stream << " int delay;" << std::endl; +#if NEW_DELAY_RESHUFFLE +#else + stream << " int seqNr;" << std::endl; +#endif + } + stream << " int name;" << std::endl; + if (_analyzer.usesEventField("invokeid")) { + stream << " int invokeid;" << std::endl; + } + } + for (std::map::iterator tIter = currDef.types.begin(); tIter != currDef.types.end(); tIter++) { + if (currDef.name.compare("_event_t") == 0 && (tIter->first.compare("name") == 0 || + tIter->first.compare("seqNr") == 0 || + tIter->first.compare("invokeid") == 0 || + tIter->first.compare("delay") == 0)) { // special treatment for _event + continue; + } + if (tIter->second.types.size() == 0) { + stream << " " << declForRange(tIter->first, tIter->second.minValue, tIter->second.maxValue, true) << ";" << std::endl; // not further nested + // 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()) { + // if (typeIter->second.types.size() > 0) { + // // an actual typedef + // stream << "hidden " << typeIter->second.name << " " << typeIter->first << ";" << std::endl; + // } else { + // stream << "hidden " << declForRange(typeIter->first, typeIter->second.minValue, typeIter->second.maxValue) << ";" << std::endl; + // } + // typeIter++; + // } + +} + + +void ChartToPromela::writeTypes(std::ostream& stream) { + stream << "/* type definitions and global variables */" << std::endl; + stream << "bool " << _prefix << "flags[6];" << std::endl; + stream << "bool " << _prefix << "config[" << _states.size() << "];" << std::endl; + stream << "bool " << _prefix << "history[" << _states.size() << "];" << std::endl; + stream << "bool " << _prefix << "invocations[" << _states.size() << "];" << std::endl; + stream << "bool " << _prefix << "initialized_data[" << _states.size() << "];" << std::endl; + + size_t tolerance = 6; + + if (_analyzer.usesComplexEventStruct()) { + // event is defined with the typedefs + stream << "_event_t " << _prefix << "_event; /* current event */" << std::endl; + stream << "chan " << _prefix << "iQ = [" << (std::max)(_internalQueueLength, (size_t)1) << "] of {_event_t} /* internal queue */" << std::endl; + stream << "chan " << _prefix << "eQ = [" << _externalQueueLength + tolerance << "] of {_event_t} /* external queue */" << std::endl; + if (_allowEventInterleaving) + stream << "chan " << _prefix << "tmpQ = [" << (std::max)(_externalQueueLength + tolerance, (size_t)1) << "] of {_event_t} /* temporary queue for external events in transitions */" << std::endl; + } else { + stream << "unsigned " << _prefix << "_event : " << BIT_WIDTH(_analyzer.getLiterals().size() + 1) << "; /* current event */" << std::endl; + stream << "chan " << _prefix << "iQ = [" << (std::max)(_internalQueueLength, (size_t)1) << "] of {int} /* internal queue */" << std::endl; + stream << "chan " << _prefix << "eQ = [" << _externalQueueLength + tolerance << "] of {int} /* external queue */" << std::endl; + if (_allowEventInterleaving) + stream << "chan " << _prefix << "tmpQ = [" << (std::max)(_externalQueueLength + tolerance, (size_t)1) << "] of {int} /* temporary queue for external events in transitions */" << std::endl; + } + + stream << std::endl; + stream << "typedef transition {" << std::endl; + stream << " unsigned source : " << BIT_WIDTH(_states.size()) << ";" << std::endl; + stream << " bool target[" << _states.size() << "];" << std::endl; + stream << " bool type[5];" << std::endl; + stream << " bool conflicts[" << _transitions.size() << "];" << std::endl; + stream << " bool exit_set[" << _states.size() << "];" << std::endl; + stream << "}" << std::endl; + if (_transitions.size() > 0) { + stream << "hidden transition " << _prefix << "transitions[" << toStr(_transitions.size()) << "];" << std::endl; + } + stream << std::endl; + + stream << "typedef state {" << std::endl; + stream << " unsigned parent : " << BIT_WIDTH(_states.size()) << ";" << std::endl; + stream << " bool children[" << _states.size() << "];" << std::endl; + stream << " bool completion[" << _states.size() << "];" << std::endl; + stream << " bool ancestors[" << _states.size() << "];" << std::endl; + stream << " bool type[8];" << std::endl; + stream << "}" << std::endl; + if (_states.size() > 0) { + stream << "hidden state " << _prefix << "states[" << toStr(_states.size()) << "];" << std::endl; + } + stream << std::endl; + + stream << "hidden int tmpIndex;" << std::endl; + if (_analyzer.usesComplexEventStruct()) { + stream << "hidden _event_t tmpE;" << std::endl; + } else { + stream << "hidden int tmpE;" << std::endl; + } + + if (_analyzer.hasIndexLessLoops()) + stream << "hidden int " << _prefix << "_index; /* helper for indexless foreach loops */" << std::endl; + + if (_analyzer.usesEventField("sendid")) + stream << "hidden int _lastSendId = 0; /* sequential counter for send ids */" << std::endl; + + if (_analyzer.usesEventField("delay")) + stream << "hidden int _lastSeqId = 0; /* sequential counter for delayed events */" << std::endl; + + stream << std::endl; + + std::set processedIdentifiers; + + // automatic types + std::list datas = DOMUtils::inDocumentOrder({ XML_PREFIX(_scxml).str() + "data" }, _scxml, false); + PromelaCodeAnalyzer::PromelaTypedef allTypes = _analyzer.getTypes(); + + for (auto data : datas) { + std::string identifier = (HAS_ATTR_CAST(data, "id") ? ATTR_CAST(data, "id") : ""); + std::string type = boost::trim_copy(HAS_ATTR_CAST(data, "type") ? ATTR_CAST(data, "type") : ""); + + _dataModelVars.insert(identifier); + if (processedIdentifiers.find(identifier) != processedIdentifiers.end()) + continue; + + processedIdentifiers.insert(identifier); + + if (boost::starts_with(type, "string")) { + type = "int" + type.substr(6, type.length() - 6); + } + + if (type.length() == 0 || type == "auto") { + if (allTypes.types.find(identifier) != allTypes.types.end()) { + type = allTypes.types[identifier].name; + } else { + LOG(ERROR) << "Automatic or no type for '" << identifier << "' but no type resolved"; + continue; + } + } + + 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); + } + std::string decl = type + " " + _prefix + identifier + arrSize; + stream << decl << ";" << std::endl; + + } + + // implicit and dynamic types + std::map::iterator typeIter = allTypes.types.begin(); + while(typeIter != allTypes.types.end()) { + if (typeIter->second.occurrences.find(this) == typeIter->second.occurrences.end()) { + typeIter++; + continue; + } + + if (processedIdentifiers.find(typeIter->first) != processedIdentifiers.end()) { + typeIter++; + continue; + } + + if (typeIter->first == "_event" + || typeIter->first == "config" + || typeIter->first == "_ioprocessors" + || typeIter->first == "_SESSIONID" + || typeIter->first == "_NAME" + || !std::any_of(typeIter->first.begin(), typeIter->first.end(), ::islower) + ) { + typeIter++; + continue; + } + + processedIdentifiers.insert(typeIter->first); + + if (typeIter->second.types.size() == 0) { + stream << "hidden " << declForRange(_prefix + typeIter->first, typeIter->second.minValue, typeIter->second.maxValue) << ";" << std::endl; + } else { + stream << "hidden " << _prefix << typeIter->second.name << " " << typeIter->first << ";" << std::endl; + } + typeIter++; + } + +} + +void ChartToPromela::writeStrings(std::ostream& stream) { + stream << "/* states, events and string literals */" << std::endl; + std::set literals = _analyzer.getLiterals(); + + { + for (size_t i = 0; i < _states.size(); i++) { + if (HAS_ATTR(_states[i], "id")) { + stream << "#define " << _prefix << _analyzer.macroForLiteral(ATTR(_states[i], "id")) << " " << toStr(i); + stream << " /* index for state " << ATTR(_states[i], "id") << " */" << std::endl; + } + } + } + + + for (auto literal : literals) { + stream << "#define " << _analyzer.macroForLiteral(literal) << " " << _analyzer.indexForLiteral(literal) << " /* " << literal << " */" << std::endl; + } +} + +void ChartToPromela::writeTransitions(std::ostream& stream) { + for (size_t i = 0; i < _transitions.size(); i++) { + DOMElement* transition(_transitions[i]); + + /** source */ + stream << " " << _prefix << "transitions[" << toStr(i) << "].source = "; + stream << ATTR_CAST(transition->getParentNode(), "documentOrder") ; + stream << ";" << std::endl; + + /** target */ + if (HAS_ATTR(transition, "targetBools")) { + std::string targetBools = ATTR(transition, "targetBools"); + for (size_t j = 0; j < _states.size(); j++) { + if (targetBools[j] == '1') + stream << " " << _prefix << "transitions[" << toStr(i) << "].target[" << toStr(j) << "] = 1;" << std::endl; + } + } + +#if 0 + /** events */ + if (HAS_ATTR(transition, "event")) { + std::list events = tokenize(ATTR(transition, "event"), ' ', true); + for(auto& event : events) { + auto trieNodes = _analyzer.getTrie().getWordsWithPrefix(event); + for(auto trieNode : trieNodes) { + stream << " " << _prefix << "transitions[" << toStr(i) << "].event[" << _analyzer.macroForLiteral(trieNode->value) << "] = 1;" << std::endl; + } + } + } +#endif + + if (!HAS_ATTR(transition, "event")) + stream << " " << _prefix << "transitions[" << toStr(i) << "].type[USCXML_TRANS_SPONTANEOUS] = 1;" << std::endl; + + if (!HAS_ATTR(transition, "target")) + stream << " " << _prefix << "transitions[" << toStr(i) << "].type[USCXML_TRANS_TARGETLESS] = 1;" << std::endl; + + if (HAS_ATTR(transition, "type") && ATTR(transition, "type") == "internal") + stream << " " << _prefix << "transitions[" << toStr(i) << "].type[USCXML_TRANS_INTERNAL] = 1;" << std::endl; + + if (TAGNAME_CAST(transition->getParentNode()) == XML_PREFIX(transition).str() + "history") + stream << " " << _prefix << "transitions[" << toStr(i) << "].type[USCXML_TRANS_HISTORY] = 1;" << std::endl; + + if (TAGNAME_CAST(transition->getParentNode()) == XML_PREFIX(transition).str() + "initial") + stream << " " << _prefix << "transitions[" << toStr(i) << "].type[USCXML_TRANS_INITIAL] = 1;" << std::endl; + + if (HAS_ATTR(transition, "conflictBools")) { + std::string conflicts = ATTR(transition, "conflictBools"); + for (auto j = 0; j < conflicts.size(); j++) { + if (conflicts[j] == '1') + stream << " " << _prefix << "transitions[" << toStr(i) << "].conflicts[" << toStr(j) << "] = 1;" << std::endl; + } + } + + if (HAS_ATTR(transition, "exitSetBools")) { + std::string exitSet = ATTR(transition, "exitSetBools"); + for (auto j = 0; j < exitSet.size(); j++) { + if (exitSet[j] == '1') + stream << " " << _prefix << "transitions[" << toStr(i) << "].exit_set[" << toStr(j) << "] = 1;" << std::endl; + } + } + + stream << std::endl; + + } +} + + + +void ChartToPromela::writeStates(std::ostream& stream) { + for (size_t i = 0; i < _states.size(); i++) { + DOMElement* state(_states[i]); + + stream << " " << _prefix << "states[" << toStr(i) << "].parent = "; + stream << (i == 0 ? "0" : ATTR_CAST(state->getParentNode(), "documentOrder")); + stream << ";" << std::endl; + + + if (HAS_ATTR(state, "childBools")) { + std::string childs = ATTR(state, "childBools"); + for (auto j = 0; j < childs.size(); j++) { + if (childs[j] == '1') + stream << " " << _prefix << "states[" << toStr(i) << "].children[" << toStr(j) << "] = 1;" << std::endl; + } + } + + if (HAS_ATTR(state, "completionBools")) { + std::string completions = ATTR(state, "completionBools"); + for (auto j = 0; j < completions.size(); j++) { + if (completions[j] == '1') + stream << " " << _prefix << "states[" << toStr(i) << "].completion[" << toStr(j) << "] = 1;" << std::endl; + } + } + + if (HAS_ATTR(state, "ancBools")) { + std::string ancestors = ATTR(state, "ancBools"); + for (auto j = 0; j < ancestors.size(); j++) { + if (ancestors[j] == '1') + stream << " " << _prefix << "states[" << toStr(i) << "].ancestors[" << toStr(j) << "] = 1;" << std::endl; + } + } + if (false) { + } else if (iequals(TAGNAME(state), "initial")) { + stream << " " << _prefix << "states[" << toStr(i) << "].type[USCXML_STATE_INITIAL] = 1;" << std::endl; + } else if (isFinal(state)) { + stream << " " << _prefix << "states[" << toStr(i) << "].type[USCXML_STATE_FINAL] = 1;" << std::endl; + } else if (isHistory(state)) { + if (HAS_ATTR(state, "type") && iequals(ATTR(state, "type"), "deep")) { + stream << " " << _prefix << "states[" << toStr(i) << "].type[USCXML_STATE_HISTORY_DEEP] = 1;" << std::endl; + } else { + stream << " " << _prefix << "states[" << toStr(i) << "].type[USCXML_STATE_HISTORY_SHALLOW] = 1;" << std::endl; + } + } else if (isAtomic(state)) { + stream << " " << _prefix << "states[" << toStr(i) << "].type[USCXML_STATE_ATOMIC] = 1;" << std::endl; + } else if (isParallel(state)) { + stream << " " << _prefix << "states[" << toStr(i) << "].type[USCXML_STATE_PARALLEL] = 1;" << std::endl; + } else if (isCompound(state)) { + stream << " " << _prefix << "states[" << toStr(i) << "].type[USCXML_STATE_COMPOUND] = 1;" << std::endl; + } else { // + stream << " " << _prefix << "states[" << toStr(i) << "].type[USCXML_STATE_COMPOUND] = 1;" << std::endl; + } + if (HAS_ATTR(state, "hasHistoryChild")) { + stream << " " << _prefix << "states[" << toStr(i) << "].type[USCXML_STATE_HAS_HISTORY] = 1;" << std::endl; + } + + stream << std::endl; + + } +} + + +void ChartToPromela::writeHelpers(std::ostream& stream) { + + +} + +void ChartToPromela::writeExecContent(std::ostream& stream, const XERCESC_NS::DOMNode* node, size_t indent) { + if (!node) + return; + + std::string padding; + for (size_t i = 0; i < indent; i++) { + padding += " "; + } + + if (node->getNodeType() == DOMNode::TEXT_NODE) { + if (boost::trim_copy(X(node->getNodeValue()).str()).length() > 0) + stream << beautifyIndentation(ADAPT_SRC(X(node->getNodeValue()).str()), indent) << std::endl; + } + + if (node->getNodeType() != DOMNode::ELEMENT_NODE) + return; // skip anything not an element + + const XERCESC_NS::DOMElement* element = static_cast(node); + + if (false) { + } else if(TAGNAME(element) == "onentry" || + TAGNAME(element) == "onexit" || + TAGNAME(element) == "transition" || + TAGNAME(element) == "finalize") { + // descent into childs and write their contents + const XERCESC_NS::DOMNode* child = node->getFirstChild(); + while(child) { + writeExecContent(stream, child, indent); + child = child->getNextSibling(); + } + } else if(TAGNAME(element) == "script") { + std::list scriptTexts = DOMUtils::filterChildType(DOMNode::TEXT_NODE, node, true); + for (auto scriptText : scriptTexts) { + stream << ADAPT_SRC(beautifyIndentation(X(scriptText->getNodeValue()).str(), indent)) << std::endl; + } + + } else if(TAGNAME(element) == "log") { + std::string label = (HAS_ATTR(element, "label") ? ATTR(element, "label") : ""); + std::string expr = (HAS_ATTR(element, "expr") ? ADAPT_SRC(ATTR(element, "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; + + if (label.size() > 0) { + if (expr.size() > 0) { + formatString += label + ": "; + } else { + formatString += label; + } + } + + if (isStringLiteral) { + formatString += expr; + } else if (expr.size() > 0) { + 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(element) == "foreach") { + stream << padding << "for (" << _prefix << (HAS_ATTR(element, "index") ? ATTR(element, "index") : "_index") << " in " << _prefix << ATTR(element, "array") << ") {" << std::endl; + if (HAS_ATTR(element, "item")) { + stream << padding << " " << _prefix << ATTR(element, "item") << " = " << _prefix << ATTR(element, "array") << "[" << _prefix << (HAS_ATTR(element, "index") ? ATTR(element, "index") : "_index") << "];" << std::endl; + } + const XERCESC_NS::DOMNode* child = element->getFirstChild(); + while(child) { + writeExecContent(stream, child, indent + 1); + child = child->getNextSibling(); + } + // if (HAS_ATTR(nodeElem, "index")) + // stream << padding << " " << _prefix << ATTR(nodeElem, "index") << "++;" << std::endl; + stream << padding << "}" << std::endl; + + } else if(TAGNAME(element) == "if") { + std::list condChain; + condChain.push_back(const_cast(element)); + + condChain.splice(condChain.end(), DOMUtils::filterChildElements(XML_PREFIX(element).str() + "elseif", element)); + condChain.splice(condChain.end(), DOMUtils::filterChildElements(XML_PREFIX(element).str() + "else", element)); + + writeIfBlock(stream, condChain, indent); + + } else if(TAGNAME(element) == "assign") { + + std::list assignTexts = DOMUtils::filterChildType(DOMNode::TEXT_NODE, element, true); + assert(assignTexts.size() > 0); + stream << beautifyIndentation(ADAPT_SRC(boost::trim_copy(X(assignTexts.front()->getNodeValue()).str())), indent) << std::endl; + + } else if(TAGNAME(element) == "send" || TAGNAME(element) == "raise") { + std::string targetQueue; + std::string insertOp = "!"; + if (TAGNAME(element) == "raise") { + targetQueue = _prefix + "iQ"; + } else if (!HAS_ATTR(element, "target")) { +// if (_allowEventInterleaving) { +// targetQueue = _prefix + "tmpQ"; +// } else { + targetQueue = _prefix + "eQ"; +// } + } else if (ATTR(element, "target").compare("#_internal") == 0) { + targetQueue = _prefix + "iQ"; + } else if (ATTR(element, "target").compare("#_parent") == 0) { + targetQueue = _parent->_prefix + "eQ"; + } else if (boost::starts_with(ATTR(element, "target"), "#_") && _machinesPerId.find(ATTR(element, "target").substr(2)) != _machinesPerId.end()) { + targetQueue = _machines[_machinesPerId[ATTR(element, "target").substr(2)]]->_prefix + "eQ"; + } + if (targetQueue.length() > 0) { + // this is for our external queue + std::string event; + + if (HAS_ATTR(element, "event")) { + event = _analyzer.macroForLiteral(ATTR(element, "event")); + } else if (HAS_ATTR(element, "eventexpr")) { + event = ADAPT_SRC(ATTR(element, "eventexpr")); + } + if (_analyzer.usesComplexEventStruct()) { + stream << padding << "{" << std::endl; + std::string typeReset = _analyzer.getTypeReset(_prefix + "_event", _analyzer.getType("_event"), padding + " "); + std::stringstream typeAssignSS; + typeAssignSS << padding << " " << _prefix << EVENT_NAME << " = " << event << ";" << std::endl; + + if (HAS_ATTR(element, "idlocation")) { + typeAssignSS << padding << " /* idlocation */" << std::endl; + typeAssignSS << padding << " _lastSendId = _lastSendId + 1;" << std::endl; + typeAssignSS << padding << " " << _prefix << ATTR(element, "idlocation") << " = _lastSendId;" << std::endl; + typeAssignSS << padding << " " << _prefix << "_event.sendid = _lastSendId;" << std::endl; + typeAssignSS << padding << " if" << std::endl; + typeAssignSS << padding << " :: _lastSendId == 2147483647 -> _lastSendId = 0;" << std::endl; + typeAssignSS << padding << " :: else -> skip;" << std::endl; + typeAssignSS << padding << " fi;" << std::endl; + } else if (HAS_ATTR(element, "id")) { + typeAssignSS << padding << " " << _prefix << "_event.sendid = " << _analyzer.macroForLiteral(ATTR(element, "id")) << ";" << std::endl; + } + + if (_invokerid.length() > 0) { // do not send invokeid if we send / raise to ourself + typeAssignSS << padding << " " << _prefix << "_event.invokeid = " << _analyzer.macroForLiteral(_invokerid) << ";" << std::endl; + } + + if (_analyzer.usesEventField("origintype") && !boost::ends_with(targetQueue, "iQ")) { + typeAssignSS << padding << " " << _prefix << "_event.origintype = " << _analyzer.macroForLiteral("http://www.w3.org/TR/scxml/#SCXMLEventProcessor") << ";" << std::endl; + } + + if (_analyzer.usesEventField("delay")) { +#if NEW_DELAY_RESHUFFLE +#else + insertOp += "!"; + typeAssignSS << padding << " _lastSeqId = _lastSeqId + 1;" << std::endl; +#endif + if (HAS_ATTR_CAST(element, "delay")) { + typeAssignSS << padding << " " << _prefix << "_event.delay = " << ATTR_CAST(element, "delay") << ";" << std::endl; + } else if (HAS_ATTR_CAST(element, "delayexpr")) { + typeAssignSS << padding << " " << _prefix << "_event.delay = " << ADAPT_SRC(ATTR_CAST(element, "delayexpr")) << ";" << std::endl; + } else { + typeAssignSS << padding << " " << _prefix << "_event.delay = 0;" << std::endl; + } +#if NEW_DELAY_RESHUFFLE +#else + typeAssignSS << padding << " " << _prefix << "_event.seqNr = _lastSeqId;" << std::endl; +#endif + } + + if (_analyzer.usesEventField("type")) { + std::string eventType = (targetQueue.compare("iQ!") == 0 ? _analyzer.macroForLiteral("internal") : _analyzer.macroForLiteral("external")); + typeAssignSS << padding << " " << _prefix << "_event.type = " << eventType << ";" << std::endl; + } + + std::list sendParams = DOMUtils::filterChildElements(XML_PREFIX(element).str() + "param", element); + std::list sendContents = DOMUtils::filterChildElements(XML_PREFIX(element).str() + "content", element); + std::string sendNameList = ATTR(element, "namelist"); + if (sendParams.size() > 0) { + for (auto sendParam : sendParams) { + typeAssignSS << padding << " " << _prefix << "_event.data." << ATTR(sendParam, "name") << " = " << ADAPT_SRC(ATTR(sendParam, "expr")) << ";" << std::endl; + } + } + if (sendNameList.size() > 0) { + std::list nameListIds = tokenize(sendNameList); + std::list::iterator nameIter = nameListIds.begin(); + while(nameIter != nameListIds.end()) { + typeAssignSS << padding << " " << _prefix << "_event.data." << *nameIter << " = " << ADAPT_SRC(*nameIter) << ";" << std::endl; + nameIter++; + } + } + + if (sendParams.size() == 0 && sendNameList.size() == 0 && sendContents.size() > 0) { + DOMElement* contentElem = sendContents.front(); + if (contentElem->hasChildNodes() && contentElem->getFirstChild()->getNodeType() == DOMNode::TEXT_NODE) { + std::string content = spaceNormalize(X(contentElem->getFirstChild()->getNodeValue()).str()); + if (!isNumeric(content.c_str(), 10)) { + typeAssignSS << padding << " " << _prefix << "_event.data = " << _analyzer.macroForLiteral(content) << ";" << std::endl; + } else { + typeAssignSS << padding << " " << _prefix << "_event.data = " << content << ";" << std::endl; + } + } else if (HAS_ATTR(contentElem, "expr")) { + typeAssignSS << padding << " " << _prefix << "_event.data = " << ADAPT_SRC(ATTR(contentElem, "expr")) << ";" << std::endl; + } + } + + // remove all fields from typeReset that are indeed set by typeAssign + // for (std::string assigned; std::getline(typeAssignSS, assigned); ) { + // assigned = assigned.substr(0, assigned.find('=')); + // assigned = assigned.substr(assigned.find('.')); + // std::istringstream typeResetSS (typeReset); + // for (std::string reset; std::getline(typeResetSS, reset); ) { + // if (!boost::find_first(reset, assigned)) { + // stream << reset << std::endl; + // } + // } + // } + // stream << typeAssignSS.str(); + + std::istringstream typeResetSS (typeReset); + for (std::string reset; std::getline(typeResetSS, reset); ) { + std::string resetField = reset.substr(0, reset.find('=')); + resetField = resetField.substr(resetField.find('.')); + for (std::string assigned; std::getline(typeAssignSS, assigned); ) { + if (boost::find_first(resetField, assigned)) { + break; + } + } + stream << reset << std::endl; + } + stream << typeAssignSS.str(); + + + stream << padding << " " << targetQueue << insertOp << _prefix <<"_event;" << std::endl; + +#if NEW_DELAY_RESHUFFLE + if (_analyzer->usesEventField("delay") && !boost::ends_with(targetQueue, "iQ")) { + stream << padding << " insertWithDelay(" << targetQueue << ");" << std::endl; + } +#endif + + stream << padding << "}" << std::endl; + } else { + stream << padding << targetQueue << insertOp << event << ";" << std::endl; + } + } + } else if(TAGNAME(element) == "cancel") { + if (HAS_ATTR(element, "sendid")) { + stream << padding << "cancelSendId(" << _analyzer.macroForLiteral(ATTR(element, "sendid")) << ", " << (_invokerid.size() > 0 ? _analyzer.macroForLiteral(_invokerid) : "0") << ");" << std::endl; + } else if (HAS_ATTR(element, "sendidexpr")) { + stream << padding << "cancelSendId(" << ADAPT_SRC(ATTR(element, "sendidexpr")) << ", " << (_invokerid.size() > 0 ? _analyzer.macroForLiteral(_invokerid) : "0") << ");" << std::endl; + } + } else { + std::cerr << "'" << TAGNAME(element) << "' not supported" << std::endl << element << std::endl; + assert(false); + } + + +} + + + +void ChartToPromela::writeFSM(std::ostream& stream) { + stream << "/* machine microstep function */" << std::endl; + stream << "#define USCXML_NUMBER_STATES " << _states.size() << std::endl; + stream << "#define USCXML_NUMBER_TRANS " << _transitions.size() << std::endl; + + stream << "proctype " << _prefix << "step() { atomic {" << std::endl; + stream << std::endl; + stream << "/* ---------------------------- */" << std::endl; + stream << "MICROSTEP:" << std::endl; + + stream << "do" << std::endl; + stream << ":: !" << _prefix << "flags[USCXML_CTX_FINISHED] -> {" << std::endl; + stream << std::endl; + + stream << "#if TRACE_EXECUTION" << std::endl; + stream << "printf(\"Taking a step\\n\");" << std::endl; + stream << "#endif" << std::endl; + + + size_t largestBitWidth = (_states.size() > _transitions.size() ? + BIT_WIDTH(_states.size() + 1) : + BIT_WIDTH(_transitions.size() + 1)); + + stream << " unsigned"; + stream << " i : " << largestBitWidth << ", "; + stream << " j : " << largestBitWidth << ", "; + stream << " k : " << largestBitWidth << ";" << std::endl; + + stream << " int err = USCXML_ERR_OK;" << std::endl; + + stream << " bool conflicts[" << _transitions.size() << "];" << std::endl; + stream << " bool trans_set[" << _transitions.size() << "];" << std::endl; + + stream << " bool target_set[" << _states.size() << "];" << std::endl; + stream << " bool exit_set[" << _states.size() << "];" << std::endl; + stream << " bool entry_set[" << _states.size() << "];" << std::endl; + stream << " bool tmp_states[" << _states.size() << "];" << std::endl; + stream << std::endl; + +#if 0 + stream << " if" << std::endl; + stream << " :: " << _prefix << "flags[USCXML_CTX_FINISHED]" << std::endl; + stream << " ACCEPT: {" << std::endl; + stream << " false;" << std::endl; + stream << " }" << std::endl; + stream << " :: else -> skip;" << std::endl; + stream << " fi;" << std::endl; + stream << std::endl; + + stream << "#if TRACE_EXECUTION" << std::endl; + stream << "printf(\"Machine not finished\\n\");" << std::endl; + stream << "#endif" << std::endl; +#endif + +#if 0 + stream << " if (ctx->flags & USCXML_CTX_TOP_LEVEL_FINAL) -> {" << std::endl; + stream << " /* exit all remaining states */" << std::endl; + stream << " i = USCXML_NUMBER_STATES;" << std::endl; + stream << " while(i-- > 0) {" << std::endl; + stream << " if (BIT_HAS(i, ctx->config)) {" << std::endl; + stream << " /* call all on exit handlers */" << std::endl; + stream << " if (USCXML_GET_STATE(i).on_exit != NULL) {" << std::endl; + stream << " if unlikely((err = USCXML_GET_STATE(i).on_exit(ctx, &USCXML_GET_STATE(i), ctx->event)) != USCXML_ERR_OK)" << std::endl; + stream << " return err;" << std::endl; + stream << " }" << std::endl; + // stream << " BIT_CLEAR(i, ctx->config);" << std::endl; + stream << " }" << std::endl; + stream << " if (BIT_HAS(i, ctx->invocations)) {" << std::endl; + stream << " if (USCXML_GET_STATE(i).invoke != NULL)" << std::endl; + stream << " USCXML_GET_STATE(i).invoke(ctx, &USCXML_GET_STATE(i), NULL, 1);" << std::endl; + stream << " BIT_CLEAR(i, ctx->invocations);" << std::endl; + stream << " }" << std::endl; + stream << " }" << std::endl; + stream << " ctx->flags |= USCXML_CTX_FINISHED;" << std::endl; + stream << " return USCXML_ERR_DONE;" << std::endl; + stream << " }" << std::endl; + stream << std::endl; + +#endif + + stream << " if" << std::endl; + stream << " ::" << _prefix << "flags[USCXML_CTX_TOP_LEVEL_FINAL] -> {" << std::endl; + stream << "#if TRACE_EXECUTION" << std::endl; + stream << "printf(\"Top level final state reached\\n\");" << std::endl; + stream << "#endif" << std::endl; + stream << " /* exit all remaining states */" << std::endl; + stream << " i = USCXML_NUMBER_STATES;" << std::endl; + stream << " do" << std::endl; + stream << " :: i > 0 -> {" << std::endl; + stream << " i = i - 1;" << std::endl; + stream << " if" << std::endl; + stream << " :: " << _prefix << "config[i] -> {" << std::endl; + stream << " /* TODO: call all on exit handlers */" << std::endl; + stream << " skip;" << std::endl; + stream << " " << std::endl; + stream << " }" << std::endl; + stream << " :: else -> skip;" << std::endl; + stream << " fi;" << std::endl; + stream << std::endl; + + stream << " if" << std::endl; + stream << " :: " << _prefix << "invocations[i] -> {" << std::endl; + stream << " /* TODO: cancel invocations */" << std::endl; + stream << " skip;" << std::endl; + stream << " " << std::endl; + stream << " }" << std::endl; + stream << " :: else -> skip;" << std::endl; + stream << " fi;" << std::endl; + stream << " }" << std::endl; + stream << " :: else -> break;" << std::endl; + stream << " od;" << std::endl; + stream << "#if TRACE_EXECUTION" << std::endl; + stream << "printf(\"Ending machine!\\n\");" << std::endl; + stream << "#endif" << std::endl; + stream << " " << _prefix << "flags[USCXML_CTX_FINISHED] = true;" << std::endl; + stream << " goto MICROSTEP;" << std::endl; + + stream << " }" << std::endl; + stream << " :: else -> skip;" << std::endl; + stream << " fi;" << std::endl; + stream << std::endl; + +#if 0 + stream << " bit_clear_all(target_set, nr_states_bytes);" << std::endl; + stream << " bit_clear_all(trans_set, nr_trans_bytes);" << std::endl; + stream << " if unlikely(ctx->flags == USCXML_CTX_PRISTINE) {" << std::endl; + stream << " if (ctx->machine->script != NULL)" << std::endl; + stream << " ctx->machine->script(ctx, &ctx->machine->states[0], NULL);" << std::endl; + stream << " bit_or(target_set, ctx->machine->states[0].completion, nr_states_bytes);" << std::endl; + stream << " ctx->flags |= USCXML_CTX_SPONTANEOUS | USCXML_CTX_INITIALIZED;" << std::endl; + stream << " goto ESTABLISH_ENTRY_SET;" << std::endl; + stream << " }" << std::endl; + stream << std::endl; +#endif + + stream << " if" << std::endl; + stream << " ::" << _prefix << "flags[USCXML_CTX_PRISTINE] -> {" << std::endl; + stream << " /* run global scripts */" << std::endl; + + std::list globalScripts = DOMUtils::filterChildElements(XML_PREFIX(_scxml).str() + "script", _scxml, false); + for (auto globalScript : globalScripts) { + writeExecContent(stream, globalScript); + } + stream << std::endl; + + stream << " /* Enter initial configuration */" << std::endl; + bit_copy(stream, _prefix + "states[0].completion", "target_set", _states.size(), 2); + stream << " " << _prefix << "flags[USCXML_CTX_SPONTANEOUS] = true;" << std::endl; + stream << " " << _prefix << "flags[USCXML_CTX_PRISTINE] = false;" << std::endl; + + stream << "#if TRACE_EXECUTION" << std::endl; + stream << "printf(\"Entering initial default completion\\n\");" << std::endl; + stream << "#endif" << std::endl; + + stream << " goto ESTABLISH_ENTRY_SET;" << std::endl; + stream << " }" << std::endl; + stream << " :: else -> skip;" << std::endl; + stream << " fi;" << std::endl; + stream << std::endl; + + +#if 0 + stream << "DEQUEUE_EVENT:" << std::endl; + stream << " if (ctx->flags & USCXML_CTX_SPONTANEOUS) {" << std::endl; + stream << " ctx->event = NULL;" << std::endl; + stream << " goto SELECT_TRANSITIONS;" << std::endl; + stream << " }" << std::endl; + stream << " if (ctx->dequeue_internal != NULL && (ctx->event = ctx->dequeue_internal(ctx)) != NULL) {" << std::endl; + stream << " goto SELECT_TRANSITIONS;" << std::endl; + stream << " }" << std::endl; + stream << std::endl; +#endif + + + stream << "/* ---------------------------- */" << std::endl; + stream << "DEQUEUE_EVENT:" << std::endl; + stream << " if" << std::endl; + stream << " ::" << _prefix << "flags[USCXML_CTX_SPONTANEOUS] -> {" << std::endl; + stream << " " << _prefix << EVENT_NAME << " = USCXML_EVENT_SPONTANEOUS;" << std::endl; + stream << "#if TRACE_EXECUTION" << std::endl; + stream << "printf(\"Trying with a spontaneuous event\\n\");" << std::endl; + stream << "#endif" << std::endl; + stream << " goto SELECT_TRANSITIONS;" << std::endl; + stream << " }" << std::endl; + stream << " :: else -> skip;" << std::endl; + stream << " fi;" << std::endl; + stream << std::endl; + + stream << " if" << std::endl; + stream << " :: len(" << _prefix << "iQ) != 0 -> {" << std::endl; + stream << " " << _prefix << "iQ ? " << _prefix << "_event;" << std::endl; + stream << "#if TRACE_EXECUTION" << std::endl; + stream << "printf(\"Deqeued an internal event\\n\");" << std::endl; + stream << "#endif" << std::endl; + stream << " goto SELECT_TRANSITIONS;" << std::endl; + stream << " }" << std::endl; + stream << " :: else -> skip;" << std::endl; + stream << " fi;" << std::endl; + + +#if 0 + stream << " /* manage invocations */" << std::endl; + stream << " for (i = 0; i < USCXML_NUMBER_STATES; i++) {" << std::endl; + stream << " /* uninvoke */" << std::endl; + stream << " if (!BIT_HAS(i, ctx->config) && BIT_HAS(i, ctx->invocations)) {" << std::endl; + stream << " if (USCXML_GET_STATE(i).invoke != NULL)" << std::endl; + stream << " USCXML_GET_STATE(i).invoke(ctx, &USCXML_GET_STATE(i), NULL, 1);" << std::endl; + stream << " BIT_CLEAR(i, ctx->invocations)" << std::endl; + stream << " }" << std::endl; + stream << " /* invoke */" << std::endl; + stream << " if (BIT_HAS(i, ctx->config) && !BIT_HAS(i, ctx->invocations)) {" << std::endl; + stream << " if (USCXML_GET_STATE(i).invoke != NULL)" << std::endl; + stream << " USCXML_GET_STATE(i).invoke(ctx, &USCXML_GET_STATE(i), NULL, 0);" << std::endl; + stream << " BIT_SET_AT(i, ctx->invocations)" << std::endl; + stream << " }" << std::endl; + stream << " }" << std::endl; + stream << std::endl; +#endif + + stream << " /* manage invocations */" << std::endl; + stream << " i = 0;" << std::endl; + stream << " do" << std::endl; + stream << " :: i < USCXML_NUMBER_STATES -> {" << std::endl; + stream << " /* uninvoke */" << std::endl; + stream << " if" << std::endl; + stream << " :: !" << _prefix << "config[i] && " << _prefix << "invocations[i] -> {" << std::endl; + stream << " skip;" << std::endl; + stream << " }" << std::endl; + stream << " :: else -> skip;" << std::endl; + stream << " fi;" << std::endl; + stream << std::endl; + + stream << " /* invoke */" << std::endl; + stream << " if" << std::endl; + stream << " :: " << _prefix << "config[i] && !" << _prefix << "invocations[i] -> {" << std::endl; + stream << " skip;" << std::endl; + stream << " }" << std::endl; + stream << " :: else -> skip;" << std::endl; + stream << " fi;" << std::endl; + stream << " i = i + 1;" << std::endl; + stream << " }" << std::endl; + stream << " :: else -> break;" << std::endl; + stream << " od;" << std::endl; + stream << std::endl; + +#if 0 + stream << " if (ctx->dequeue_external != NULL && (ctx->event = ctx->dequeue_external(ctx)) != NULL) {" << std::endl; + stream << " goto SELECT_TRANSITIONS;" << std::endl; + stream << " }" << std::endl; + stream << std::endl; + stream << " if (ctx->dequeue_external == NULL) {" << std::endl; + stream << " return USCXML_ERR_DONE;" << std::endl; + stream << " }" << std::endl; + stream << " return USCXML_ERR_IDLE;" << std::endl; + stream << std::endl; +#endif + + stream << " if" << std::endl; + stream << " :: len(" << _prefix << "eQ) != 0 -> {" << std::endl; + stream << " " << _prefix << "eQ ? " << _prefix << "_event;" << std::endl; + stream << "#if TRACE_EXECUTION" << std::endl; + stream << "printf(\"Deqeued an external event\\n\");" << std::endl; + stream << "#endif" << std::endl; + stream << " goto SELECT_TRANSITIONS;" << std::endl; + stream << " }" << std::endl; +// stream << " :: else -> quit;" << std::endl; + stream << " fi;" << std::endl; + stream << std::endl; + +#if 0 + stream << "SELECT_TRANSITIONS:" << std::endl; + stream << " bit_clear_all(conflicts, nr_trans_bytes);" << std::endl; + stream << " bit_clear_all(exit_set, nr_states_bytes);" << std::endl; + stream << " for (i = 0; i < USCXML_NUMBER_TRANS; i++) {" << std::endl; + stream << " /* never select history or initial transitions automatically */" << std::endl; + stream << " if unlikely(USCXML_GET_TRANS(i).type & (USCXML_TRANS_HISTORY | USCXML_TRANS_INITIAL))" << std::endl; + stream << " continue;" << std::endl; + stream << std::endl; + stream << " /* is the transition active? */" << std::endl; + stream << " if (BIT_HAS(USCXML_GET_TRANS(i).source, ctx->config)) {" << std::endl; + stream << " /* is it non-conflicting? */" << std::endl; + stream << " if (!BIT_HAS(i, conflicts)) {" << std::endl; + stream << " /* is it spontaneous with an event or vice versa? */" << std::endl; + stream << " if ((USCXML_GET_TRANS(i).event == NULL && ctx->event == NULL) || " << std::endl; + stream << " (USCXML_GET_TRANS(i).event != NULL && ctx->event != NULL)) {" << std::endl; + stream << " /* is it enabled? */" << std::endl; + stream << " if ((ctx->event == NULL || ctx->is_matched(ctx, &USCXML_GET_TRANS(i), ctx->event) > 0) &&" << std::endl; + stream << " (USCXML_GET_TRANS(i).condition == NULL || " << std::endl; + stream << " USCXML_GET_TRANS(i).is_enabled(ctx, &USCXML_GET_TRANS(i)) > 0)) {" << std::endl; + stream << " /* remember that we found a transition */" << std::endl; + stream << " ctx->flags |= USCXML_CTX_TRANSITION_FOUND;" << std::endl; + stream << std::endl; + + stream << " /* transitions that are pre-empted */" << std::endl; + stream << " bit_or(conflicts, USCXML_GET_TRANS(i).conflicts, nr_trans_bytes);" << std::endl; + stream << std::endl; + stream << " /* states that are directly targeted (resolve as entry-set later) */" << std::endl; + stream << " bit_or(target_set, USCXML_GET_TRANS(i).target, nr_states_bytes);" << std::endl; + stream << std::endl; + stream << " /* states that will be left */" << std::endl; + stream << " bit_or(exit_set, USCXML_GET_TRANS(i).exit_set, nr_states_bytes);" << std::endl; + stream << std::endl; + stream << " BIT_SET_AT(i, trans_set);" << std::endl; + stream << " }" << std::endl; + stream << " }" << std::endl; + stream << " }" << std::endl; + stream << " }" << std::endl; + stream << " }" << std::endl; + stream << " bit_and(exit_set, ctx->config, nr_states_bytes);" << std::endl; + stream << std::endl; +#endif + + stream << "/* ---------------------------- */" << std::endl; + stream << "SELECT_TRANSITIONS:" << std::endl; + bit_clear_all(stream, "conflicts", _transitions.size(), 1); + bit_clear_all(stream, "trans_set", _transitions.size(), 1); + bit_clear_all(stream, "target_set", _states.size(), 1); + bit_clear_all(stream, "exit_set", _states.size(), 1); + stream << "#if TRACE_EXECUTION" << std::endl; + stream << "printf(\"Establishing optimal transition set for event %d\\n\", " << _prefix << EVENT_NAME << ");" << std::endl; + stream << "#endif" << std::endl; + stream << " " << _prefix << "flags[USCXML_CTX_TRANSITION_FOUND] = false;" << std::endl; + stream << " i = 0;" << std::endl; + stream << " do" << std::endl; + stream << " :: i < USCXML_NUMBER_TRANS -> {" << std::endl; + + stream << " /* only select non-history, non-initial transitions */" << std::endl; + stream << " if" << std::endl; + stream << " :: !" << _prefix << "transitions[i].type[USCXML_TRANS_HISTORY] &&" << std::endl; + stream << " !" << _prefix << "transitions[i].type[USCXML_TRANS_INITIAL] -> {" << std::endl; + + stream << " if" << std::endl; + stream << " :: /* is the transition active? */" << std::endl; + stream << " " << _prefix << "config[" << _prefix << "transitions[i].source] && " << std::endl; + stream << std::endl; + stream << " /* is it non-conflicting? */" << std::endl; + stream << " !conflicts[i] && " << std::endl; + stream << std::endl; + stream << " /* is it spontaneous with an event or vice versa? */" << std::endl; + stream << " ((" << _prefix << EVENT_NAME << " == USCXML_EVENT_SPONTANEOUS && " << std::endl; + stream << " " << _prefix << "transitions[i].type[USCXML_TRANS_SPONTANEOUS]) || " << std::endl; + stream << " (" << _prefix << EVENT_NAME << " != USCXML_EVENT_SPONTANEOUS && " << std::endl; + stream << " !" << _prefix << "transitions[i].type[USCXML_TRANS_SPONTANEOUS])) &&" << std::endl; + stream << std::endl; + stream << " /* is it matching and enabled? */" << std::endl; + stream << " (false " << std::endl; + + + for (auto i = 0; i < _transitions.size(); i++) { + stream << " || (i == " << toStr(i); + if (HAS_ATTR(_transitions[i], "event") && ATTR(_transitions[i], "event") != "*") { + stream << " && (false"; + std::list events =_analyzer.getTrie().getWordsWithPrefix(ATTR(_transitions[i], "event")); + for (auto event : events) { + stream << " || " << _prefix << EVENT_NAME << " == " << _analyzer.macroForLiteral(event->value); + } + stream << ")"; + } + if (HAS_ATTR(_transitions[i], "cond")) { + stream << " && " << ADAPT_SRC(ATTR(_transitions[i], "cond")); + } + stream << ")" << std::endl; + } + + stream << " ) -> {" << std::endl; + + stream << " /* remember that we found a transition */" << std::endl; + stream << " " << _prefix << "flags[USCXML_CTX_TRANSITION_FOUND] = true;" << std::endl; + stream << std::endl; + + stream << " /* transitions that are pre-empted */" << std::endl; + bit_or(stream, "conflicts", _prefix + "transitions[i].conflicts", _transitions.size(), 4); + stream << std::endl; + + stream << " /* states that are directly targeted (resolve as entry-set later) */" << std::endl; + bit_or(stream, "target_set", _prefix + "transitions[i].target", _states.size(), 4); + stream << std::endl; + + stream << " /* states that will be left */" << std::endl; + bit_or(stream, "exit_set", _prefix + "transitions[i].exit_set", _states.size(), 4); + stream << std::endl; + + stream << " trans_set[i] = true;" << std::endl; + + + stream << " }" << std::endl; + stream << " :: else {" << std::endl; + stream << " skip;" << std::endl; + stream << " }" << std::endl; + stream << " fi" << std::endl; + stream << " }" << std::endl; + stream << " :: else -> break;" << std::endl; + stream << " fi" << std::endl; + + stream << " i = i + 1;" << std::endl; + stream << " }" << std::endl; + stream << " :: else -> break;" << std::endl; + stream << " od;" << std::endl; + + stream << "#if TRACE_EXECUTION" << std::endl; + stream << "printf(\"Selected Transitions: \");" << std::endl; + printBitArray(stream, "trans_set", _transitions.size()); + stream << "printf(\"\\n\");" << std::endl; + stream << "#endif" << std::endl; + + stream << "#if TRACE_EXECUTION" << std::endl; + stream << "printf(\"Target Set: \");" << std::endl; + printBitArray(stream, "target_set", _states.size()); + stream << "printf(\"\\n\");" << std::endl; + stream << "#endif" << std::endl; + +#if 0 + stream << " if (ctx->flags & USCXML_CTX_TRANSITION_FOUND) {" << std::endl; + stream << " ctx->flags |= USCXML_CTX_SPONTANEOUS;" << std::endl; + stream << " ctx->flags &= ~USCXML_CTX_TRANSITION_FOUND;" << std::endl; + stream << " } else {" << std::endl; + stream << " ctx->flags &= ~USCXML_CTX_SPONTANEOUS;" << std::endl; + stream << " goto DEQUEUE_EVENT;" << std::endl; + stream << " }" << std::endl; + stream << std::endl; +#endif + + stream << " if" << std::endl; + stream << " :: " << _prefix << "flags[USCXML_CTX_TRANSITION_FOUND] -> {" << std::endl; + stream << "#if TRACE_EXECUTION" << std::endl; + stream << "printf(\"Found transitions\\n\");" << std::endl; + stream << "#endif" << std::endl; + stream << " " << _prefix << "flags[USCXML_CTX_SPONTANEOUS] = true;" << std::endl; + stream << " " << _prefix << "flags[USCXML_CTX_TRANSITION_FOUND] = false;" << std::endl; + stream << " }" << std::endl; + stream << " :: else {" << std::endl; + stream << " " << _prefix << "flags[USCXML_CTX_SPONTANEOUS] = false;" << std::endl; + stream << "#if TRACE_EXECUTION" << std::endl; + stream << "printf(\"Found NO transitions\\n\");" << std::endl; + stream << "#endif" << std::endl; + stream << " goto DEQUEUE_EVENT;" << std::endl; + stream << " }" << std::endl; + stream << " fi" << std::endl; + stream << std::endl; + +#if 0 + stream << "/* REMEMBER_HISTORY: */" << std::endl; + stream << " for (i = 0; i < USCXML_NUMBER_STATES; i++) {" << std::endl; + stream << " if unlikely(USCXML_STATE_MASK(USCXML_GET_STATE(i).type) == USCXML_STATE_HISTORY_SHALLOW ||" << std::endl; + stream << " USCXML_STATE_MASK(USCXML_GET_STATE(i).type) == USCXML_STATE_HISTORY_DEEP) {" << std::endl; + stream << " /* a history state whose parent is about to be exited */" << std::endl; + stream << " if unlikely(BIT_HAS(USCXML_GET_STATE(i).parent, exit_set)) {" << std::endl; + stream << " bit_copy(tmp_states, USCXML_GET_STATE(i).completion, nr_states_bytes);" << std::endl; + stream << std::endl; + stream << " /* set those states who were enabled */" << std::endl; + stream << " bit_and(tmp_states, ctx->config, nr_states_bytes);" << std::endl; + stream << std::endl; + stream << " /* clear current history with completion mask */" << std::endl; + stream << " bit_and_not(ctx->history, USCXML_GET_STATE(i).completion, nr_states_bytes);" << std::endl; + stream << std::endl; + stream << " /* set history */" << std::endl; + stream << " bit_or(ctx->history, tmp_states, nr_states_bytes);" << std::endl; + stream << " }" << std::endl; + stream << " }" << std::endl; + stream << " }" << std::endl; + stream << std::endl; +#endif + + stream << "/* ---------------------------- */" << std::endl; + stream << "/* REMEMBER_HISTORY: */" << std::endl; + stream << "#if TRACE_EXECUTION" << std::endl; + stream << "printf(\"Save history configurations\\n\");" << std::endl; + stream << "#endif" << std::endl; + stream << " i = 0;" << std::endl; + stream << " do" << std::endl; + stream << " :: i < USCXML_NUMBER_STATES -> {" << std::endl; + + stream << " if" << std::endl; + stream << " :: " << _prefix << "states[i].type[USCXML_STATE_HISTORY_SHALLOW] ||" << std::endl; + stream << " " << _prefix << "states[i].type[USCXML_STATE_HISTORY_DEEP] -> {" << std::endl; + stream << " if" << std::endl; + stream << " :: exit_set[" << _prefix << "states[i].parent] -> {" << std::endl; + stream << " /* a history state whose parent is about to be exited */" << std::endl; + + bit_copy(stream, _prefix + "states[i].completion", "tmp_states", _states.size(), 3); + bit_and(stream, "tmp_states", _prefix + "config", _states.size(), 3); + bit_and_not(stream, "tmp_states", _prefix + "states[i].completion", _states.size(), 3); + bit_or(stream, _prefix + "history", "tmp_states", _states.size(), 3); + stream << std::endl; + + stream << " }" << std::endl; + stream << " :: else -> skip;" << std::endl; + stream << " fi;" << std::endl; + stream << " }" << std::endl; + stream << " :: else -> skip;" << std::endl; + stream << " fi;" << std::endl; + + + stream << " i = i + 1;" << std::endl; + stream << " }" << std::endl; + stream << " :: else -> break;" << std::endl; + stream << " od;" << std::endl; + stream << std::endl; + +#if 0 + stream << "ESTABLISH_ENTRY_SET:" << std::endl; + stream << " /* calculate new entry set */" << std::endl; + stream << " bit_copy(entry_set, target_set, nr_states_bytes);" << std::endl; + stream << std::endl; + stream << " /* iterate for ancestors */" << std::endl; + stream << " for (i = 0; i < USCXML_NUMBER_STATES; i++) {" << std::endl; + stream << " if (BIT_HAS(i, entry_set)) {" << std::endl; + stream << " bit_or(entry_set, USCXML_GET_STATE(i).ancestors, nr_states_bytes);" << std::endl; + stream << " }" << std::endl; + stream << " }" << std::endl; + stream << std::endl; +#endif + + stream << "/* ---------------------------- */" << std::endl; + stream << "ESTABLISH_ENTRY_SET:" << std::endl; + stream << " /* calculate new entry set */" << std::endl; + bit_copy(stream, "target_set", "entry_set", _states.size(), 1); + stream << std::endl; + + stream << " i = 0;" << std::endl; + stream << " do" << std::endl; + stream << " :: i < USCXML_NUMBER_STATES -> {" << std::endl; + + stream << " if" << std::endl; + stream << " :: entry_set[i] -> {" << std::endl; + stream << " /* ancestor completion */" << std::endl; + bit_or(stream, "entry_set", _prefix + "states[i].ancestors", _states.size(), 3); + + stream << " }" << std::endl; + stream << " :: else -> skip;" << std::endl; + stream << " fi;" << std::endl; + + stream << " i = i + 1;" << std::endl; + stream << " }" << std::endl; + stream << " :: else -> break;" << std::endl; + stream << " od;" << std::endl; + stream << std::endl; + + stream << "#if TRACE_EXECUTION" << std::endl; + stream << "printf(\"Entry Set (after ancestor completion)\");" << std::endl; + printBitArray(stream, "entry_set", _states.size()); + stream << "printf(\"\\n\");" << std::endl; + stream << "#endif" << std::endl; + +#if 0 + stream << " /* iterate for descendants */" << std::endl; + stream << " for (i = 0; i < USCXML_NUMBER_STATES; i++) {" << std::endl; + stream << " if (BIT_HAS(i, entry_set)) {" << std::endl; + stream << " switch (USCXML_STATE_MASK(USCXML_GET_STATE(i).type)) {" << std::endl; +#endif + + stream << " /* iterate for descendants */" << std::endl; + stream << " i = 0;" << std::endl; + stream << " do" << std::endl; + stream << " :: i < USCXML_NUMBER_STATES -> {" << std::endl; + stream << " if" << std::endl; + stream << " :: entry_set[i] -> {" << std::endl; + stream << " if" << std::endl; + +#if 0 + stream << " case USCXML_STATE_PARALLEL: {" << std::endl; + stream << " bit_or(entry_set, USCXML_GET_STATE(i).completion, nr_states_bytes);" << std::endl; + stream << " break;" << std::endl; + stream << " }" << std::endl; +#endif + + stream << " :: " << _prefix << "states[i].type[USCXML_STATE_PARALLEL] -> {" << std::endl; + bit_or(stream, "entry_set", _prefix + "states[i].completion", _states.size(), 4); + stream << " }" << std::endl; + + +#if 0 + stream << " case USCXML_STATE_HISTORY_SHALLOW:" << std::endl; + stream << " case USCXML_STATE_HISTORY_DEEP: {" << std::endl; + stream << " if (!bit_has_and(USCXML_GET_STATE(i).completion, ctx->history, nr_states_bytes) &&" << std::endl; + stream << " !BIT_HAS(USCXML_GET_STATE(i).parent, ctx->config)) {" << std::endl; + stream << " /* nothing set for history, look for a default transition */" << std::endl; + stream << " for (j = 0; j < USCXML_NUMBER_TRANS; j++) {" << std::endl; + stream << " if unlikely(ctx->machine->transitions[j].source == i) {" << std::endl; + stream << " bit_or(entry_set, ctx->machine->transitions[j].target, nr_states_bytes);" << std::endl; + stream << " if(USCXML_STATE_MASK(USCXML_GET_STATE(i).type) == USCXML_STATE_HISTORY_DEEP &&" << std::endl; + stream << " !bit_has_and(ctx->machine->transitions[j].target, USCXML_GET_STATE(i).children, nr_states_bytes)) {" << std::endl; + stream << " for (k = i + 1; k < USCXML_NUMBER_STATES; k++) {" << std::endl; + stream << " if (BIT_HAS(k, ctx->machine->transitions[j].target)) {" << std::endl; + stream << " bit_or(entry_set, ctx->machine->states[k].ancestors, nr_states_bytes);" << std::endl; + stream << " break;" << std::endl; + stream << " }" << std::endl; + stream << " }" << std::endl; + stream << " }" << std::endl; + stream << " BIT_SET_AT(j, trans_set);" << std::endl; + stream << " break;" << std::endl; + stream << " }" << std::endl; + stream << " /* Note: SCXML mandates every history to have a transition! */" << std::endl; + stream << " }" << std::endl; + stream << " } else {" << std::endl; + stream << " bit_copy(tmp_states, USCXML_GET_STATE(i).completion, nr_states_bytes);" << std::endl; + stream << " bit_and(tmp_states, ctx->history, nr_states_bytes);" << std::endl; + stream << " bit_or(entry_set, tmp_states, nr_states_bytes);" << std::endl; + stream << " if (USCXML_GET_STATE(i).type == (USCXML_STATE_HAS_HISTORY | USCXML_STATE_HISTORY_DEEP)) {" << std::endl; + stream << " /* a deep history state with nested histories -> more completion */" << std::endl; + stream << " for (j = i + 1; j < USCXML_NUMBER_STATES; j++) {" << std::endl; + stream << " if (BIT_HAS(j, USCXML_GET_STATE(i).completion) &&" << std::endl; + stream << " BIT_HAS(j, entry_set) &&" << std::endl; + stream << " (ctx->machine->states[j].type & USCXML_STATE_HAS_HISTORY)) {" << std::endl; + stream << " for (k = j + 1; k < USCXML_NUMBER_STATES; k++) {" << std::endl; + stream << " /* add nested history to entry_set */" << std::endl; + stream << " if ((USCXML_STATE_MASK(ctx->machine->states[k].type) == USCXML_STATE_HISTORY_DEEP ||" << std::endl; + stream << " USCXML_STATE_MASK(ctx->machine->states[k].type) == USCXML_STATE_HISTORY_SHALLOW) &&" << std::endl; + stream << " BIT_HAS(k, ctx->machine->states[j].children)) {" << std::endl; + stream << " /* a nested history state */" << std::endl; + stream << " BIT_SET_AT(k, entry_set);" << std::endl; + stream << " }" << std::endl; + stream << " }" << std::endl; + stream << " }" << std::endl; + stream << " }" << std::endl; + stream << " }" << std::endl; + stream << " }" << std::endl; + stream << " break;" << std::endl; + stream << " }" << std::endl; +#endif + + + stream << " :: " << _prefix << "states[i].type[USCXML_STATE_HISTORY_SHALLOW] ||" << std::endl; + stream << " " << _prefix << "states[i].type[USCXML_STATE_HISTORY_DEEP] -> {" << std::endl; + stream << " if" << std::endl; + stream << " :: !"; + bit_has_and(stream, _prefix + "states[i].completion", _prefix + "history", _states.size(), 5); + stream << " && !" << _prefix << "config[" << _prefix << "states[i].parent]" << " -> {" << std::endl; + stream << " /* nothing set for history, look for a default transition */" << std::endl; + stream << " j = 0;" << std::endl; + stream << " do" << std::endl; + stream << " :: j < USCXML_NUMBER_TRANS -> {" << std::endl; + stream << " if" << std::endl; + stream << " :: " << _prefix << "transitions[j].source == i -> {" << std::endl; + + bit_or(stream, "entry_set", _prefix + "transitions[j].target", _states.size(), 8); + stream << std::endl; + stream << " if" << std::endl; + stream << " :: (" << _prefix << "states[i].type[USCXML_STATE_HISTORY_DEEP] &&" << std::endl; + stream << " !"; + bit_has_and(stream, _prefix + "transitions[j].target", _prefix + "states[i].children", _states.size(), 10); + stream << " ) -> {" << std::endl; + stream << " k = i + 1" << std::endl; + stream << " do" << std::endl; + stream << " :: k < USCXML_NUMBER_STATES -> {" << std::endl; + stream << " if" << std::endl; + stream << " :: " << _prefix << "transitions[j].target[k] -> {" << std::endl; + bit_or(stream, "entry_set", _prefix + "states[k].ancestors", _states.size(), 11); + stream << " break;" << std::endl; + stream << std::endl; + stream << " }" << std::endl; + stream << " :: else -> skip;" << std::endl; + stream << " fi" << std::endl; + stream << " }" << std::endl; + stream << " :: else -> break;" << std::endl; + stream << " od" << std::endl; + stream << " trans_set[j] = true;" << std::endl; + stream << " break;" << std::endl; + stream << " }" << std::endl; + stream << " :: else -> skip;" << std::endl; + stream << " fi" << std::endl; + + stream << " }" << std::endl; + stream << " :: else -> skip;" << std::endl; + stream << " fi" << std::endl; + stream << " j = j + 1;" << std::endl; + stream << " }" << std::endl; + stream << " :: else -> break" << std::endl; + stream << " od" << std::endl; + stream << " skip;" << std::endl; + stream << " }" << std::endl; + stream << " :: else -> {" << std::endl; + bit_copy(stream, "tmp_states", _prefix + "states[i].completion", _states.size(), 5); + bit_and(stream, "tmp_states", _prefix + "history", _states.size(), 5); + bit_or(stream, "entry_set", "tmp_states", _states.size(), 5); + stream << " if" << std::endl; + stream << " :: " << _prefix << "states[i].type[USCXML_STATE_HAS_HISTORY] ||" << std::endl; + stream << " " << _prefix << "states[i].type[USCXML_STATE_HISTORY_DEEP] -> { " << std::endl; + stream << " /* a deep history state with nested histories -> more completion */" << std::endl; + stream << " j = i + 1;" << std::endl; + stream << " do" << std::endl; + stream << " :: j < USCXML_NUMBER_STATES -> {" << std::endl; + stream << " if" << std::endl; + stream << " :: (" << _prefix << "states[i].completion[j] &&" << std::endl; + stream << " entry_set[j] && " << std::endl; + stream << " " << _prefix << "states[j].type[USCXML_STATE_HAS_HISTORY]) -> {" << std::endl; + stream << " k = j + 1;" << std::endl; + stream << " do" << std::endl; + stream << " :: k < USCXML_NUMBER_STATES -> {" << std::endl; + stream << " /* add nested history to entry_set */" << std::endl; + stream << " k = k + 1;" << std::endl; + stream << " if" << std::endl; + stream << " :: (" << _prefix << "states[k].type[USCXML_STATE_HISTORY_DEEP] ||" << std::endl; + stream << " " << _prefix << "states[k].type[USCXML_STATE_HISTORY_SHALLOW]) &&" << std::endl; + stream << " " << _prefix << "states[j].children[k] -> {" << std::endl; + stream << " /* a nested history state */" << std::endl; + stream << " entry_set[k] = true;" << std::endl; + stream << " }" << std::endl; + stream << " :: else -> skip;" << std::endl; + stream << " fi" << std::endl; + stream << " }" << std::endl; + stream << " :: else -> break;" << std::endl; + stream << " od" << std::endl; + stream << " }" << std::endl; + stream << " :: else -> skip;" << std::endl; + stream << " fi" << std::endl; + stream << " }" << std::endl; + stream << " :: else -> break;" << std::endl; + stream << " od" << std::endl; + stream << " }" << std::endl; + stream << " :: else -> skip;" << std::endl; + stream << " fi" << std::endl; + + stream << " }" << std::endl; + stream << " fi;" << std::endl; + + stream << " }" << std::endl; + +#if 0 + stream << " case USCXML_STATE_INITIAL: {" << std::endl; + stream << " for (j = 0; j < USCXML_NUMBER_TRANS; j++) {" << std::endl; + stream << " if (ctx->machine->transitions[j].source == i) {" << std::endl; + stream << " BIT_SET_AT(j, trans_set);" << std::endl; + stream << " BIT_CLEAR(i, entry_set);" << std::endl; + stream << " bit_or(entry_set, ctx->machine->transitions[j].target, nr_states_bytes);" << std::endl; + stream << " for (k = i + 1; k < USCXML_NUMBER_STATES; k++) {" << std::endl; + stream << " if (BIT_HAS(k, ctx->machine->transitions[j].target)) {" << std::endl; + stream << " bit_or(entry_set, ctx->machine->states[k].ancestors, nr_states_bytes);" << std::endl; + stream << " }" << std::endl; + stream << " }" << std::endl; + stream << " }" << std::endl; + stream << " }" << std::endl; + stream << " break;" << std::endl; + stream << " }" << std::endl; +#endif + + stream << " :: " << _prefix << "states[i].type[USCXML_STATE_INITIAL] -> {" << std::endl; + stream << " j = 0" << std::endl; + stream << " do" << std::endl; + stream << " :: j < USCXML_NUMBER_TRANS -> {" << std::endl; + stream << " if" << std::endl; + stream << " :: " << _prefix << "transitions[j].source == i -> {" << std::endl; + stream << " trans_set[j] = true;" << std::endl; + stream << " entry_set[i] = false;" << std::endl; + + bit_or(stream, "entry_set", _prefix + "transitions[j].target", _states.size(), 6); + stream << std::endl; + + stream << " k = i + 1;" << std::endl; + stream << " do" << std::endl; + stream << " :: k < USCXML_NUMBER_STATES -> {" << std::endl; + stream << " if" << std::endl; + stream << " :: " << _prefix << "transitions[j].target[k] -> {" << std::endl; + + bit_or(stream, "entry_set", _prefix + "states[k].ancestors", _states.size(), 8); + stream << std::endl; + + stream << " }" << std::endl; + stream << " :: else -> break;" << std::endl; + stream << " fi" << std::endl; + stream << " k = k + 1;" << std::endl; + stream << " }" << std::endl; + stream << " :: else -> break" << std::endl; + stream << " od" << std::endl; + stream << " }" << std::endl; + stream << " :: else -> break;" << std::endl; + stream << " fi" << std::endl; + stream << " j = j + 1;" << std::endl; + stream << " }" << std::endl; + stream << " :: else -> break" << std::endl; + stream << " od;" << std::endl; + + stream << " }" << std::endl; + + +#if 0 + stream << " case USCXML_STATE_COMPOUND: { /* we need to check whether one child is already in entry_set */" << std::endl; + stream << " if (!bit_has_and(entry_set, USCXML_GET_STATE(i).children, nr_states_bytes) &&" << std::endl; + stream << " (!bit_has_and(ctx->config, USCXML_GET_STATE(i).children, nr_states_bytes) ||" << std::endl; + stream << " bit_has_and(exit_set, USCXML_GET_STATE(i).children, nr_states_bytes)))" << std::endl; + stream << " {" << std::endl; + stream << " bit_or(entry_set, USCXML_GET_STATE(i).completion, nr_states_bytes);" << std::endl; + stream << " if (!bit_has_and(USCXML_GET_STATE(i).completion, USCXML_GET_STATE(i).children, nr_states_bytes)) {" << std::endl; + stream << " /* deep completion */" << std::endl; + stream << " for (j = i + 1; j < USCXML_NUMBER_STATES; j++) {" << std::endl; + stream << " if (BIT_HAS(j, USCXML_GET_STATE(i).completion)) {" << std::endl; + stream << " bit_or(entry_set, ctx->machine->states[j].ancestors, nr_states_bytes);" << std::endl; + stream << " break; /* completion of compound is single state */" << std::endl; + stream << " }" << std::endl; + stream << " }" << std::endl; + stream << " }" << std::endl; + stream << " }" << std::endl; + stream << " break;" << std::endl; + stream << " }" << std::endl; + stream << " }" << std::endl; + stream << " }" << std::endl; + stream << " }" << std::endl; + stream << std::endl; +#endif + + stream << " :: " << _prefix << "states[i].type[USCXML_STATE_COMPOUND] -> {" << std::endl; + + stream << "#if TRACE_EXECUTION" << std::endl; + stream << "printf(\"Descendant completion for compound state %d\\n\", i);" << std::endl; + stream << "#endif" << std::endl; + + stream << " /* we need to check whether one child is already in entry_set */" << std::endl; + stream << " if" << std::endl; + stream << " :: (" << std::endl; + stream << " !"; + bit_has_and(stream, "entry_set", _prefix + "states[i].children", _states.size(), 5); + stream << " && " << std::endl; + stream << " (!"; + bit_has_and(stream, _prefix + "config", _prefix + "states[i].children", _states.size(), 5); + stream << " || " << std::endl; + bit_has_and(stream, "exit_set", _prefix + "states[i].children", _states.size(), 5); + stream << ")) "<< std::endl; + stream << " -> {" << std::endl; + + bit_or(stream, "entry_set", _prefix + "states[i].completion", _states.size(), 5); + + stream << " if" << std::endl; + stream << " :: ("; + bit_has_and(stream, _prefix + "states[i].completion", _prefix + "states[i].children", _states.size(), 5); + stream << std::endl; + stream << " ) -> {" << std::endl; + stream << " /* deep completion */" << std::endl; + stream << " j = i + 1;" << std::endl; + stream << " do" << std::endl; + stream << " :: j < USCXML_NUMBER_STATES - 1 -> {" << std::endl; + stream << " j = j + 1;" << std::endl; + stream << " if" << std::endl; + stream << " :: " << _prefix << "states[i].completion[j] -> {" << std::endl; + + bit_or(stream, "entry_set", _prefix + "states[j].ancestors", _states.size(), 9); + stream << std::endl; + + stream << " /* completion of compound is single state */" << std::endl; + stream << " break;" << std::endl; + stream << " } " << std::endl; + stream << " :: else -> skip;" << std::endl; + stream << " fi" << std::endl; + stream << " }" << std::endl; + stream << " :: else -> break;" << std::endl; + stream << " od" << std::endl; + + stream << " }" << std::endl; + stream << " :: else -> skip;" << std::endl; + stream << " fi" << std::endl; + + stream << " }" << std::endl; + stream << " :: else -> skip;" << std::endl; + stream << " fi" << std::endl; + stream << " }" << std::endl; + + stream << " :: else -> skip;" << std::endl; + stream << " fi;" << std::endl; + stream << " }" << std::endl; + stream << " :: else -> skip;" << std::endl; + stream << " fi;" << std::endl; + stream << " i = i + 1;" << std::endl; + stream << " }" << std::endl; + stream << " :: else -> break;" << std::endl; + stream << " od;" << std::endl; + stream << std::endl; + +#if 0 + stream << "/* EXIT_STATES: */" << std::endl; + stream << " i = USCXML_NUMBER_STATES;" << std::endl; + stream << " while(i-- > 0) {" << std::endl; + stream << " if (BIT_HAS(i, exit_set) && BIT_HAS(i, ctx->config)) {" << std::endl; + stream << " /* call all on exit handlers */" << std::endl; + stream << " if (USCXML_GET_STATE(i).on_exit != NULL) {" << std::endl; + stream << " if unlikely((err = USCXML_GET_STATE(i).on_exit(ctx, &USCXML_GET_STATE(i), ctx->event)) != USCXML_ERR_OK)" << std::endl; + stream << " return err;" << std::endl; + stream << " }" << std::endl; + stream << " BIT_CLEAR(i, ctx->config);" << std::endl; + stream << " }" << std::endl; + stream << " }" << std::endl; + stream << std::endl; +#endif + + stream << "#if TRACE_EXECUTION" << std::endl; + stream << "printf(\"Entry Set (after descendant completion)\");" << std::endl; + printBitArray(stream, "entry_set", _states.size()); + stream << "printf(\"\\n\");" << std::endl; + stream << "#endif" << std::endl; + + stream << "/* ---------------------------- */" << std::endl; + stream << "/* EXIT_STATES: */" << std::endl; + stream << " i = USCXML_NUMBER_STATES;" << std::endl; + stream << " do" << std::endl; + stream << " :: i > 0 -> {" << std::endl; + stream << " i = i - 1;" << std::endl; + stream << " if" << std::endl; + stream << " :: exit_set[i] && " << _prefix << "config[i] -> {" << std::endl; + stream << " /* call all on-exit handlers */" << std::endl; + + stream << " if" << std::endl; + for (auto i = 0; i < _states.size(); i++) { + std::list onentries = DOMUtils::filterChildElements(XML_PREFIX(_states[i]).str() + "onexit" , _states[i]); + if (onentries.size() > 0) { + stream << " :: i == " << toStr(i) << " -> {" << std::endl; + for (auto onentry : onentries) + writeExecContent(stream, onentry, 3); + stream << " }" << std::endl; + } + } + stream << " :: else ->skip;" << std::endl; + stream << " fi" << std::endl; + stream << std::endl; + + + stream << " " << _prefix << "config[i] = false;" << std::endl; + stream << " skip;" << std::endl; + stream << " }" << std::endl; + stream << " :: else -> skip;" << std::endl; + stream << " fi;" << std::endl; + stream << " }" << std::endl; + stream << " :: else -> break;" << std::endl; + stream << " od;" << std::endl; + stream << std::endl; + + stream << "#if TRACE_EXECUTION" << std::endl; + stream << "printf(\"Exited States\\n\");" << std::endl; + stream << "#endif" << std::endl; + +#if 0 + stream << "/* TAKE_TRANSITIONS: */" << std::endl; + stream << " for (i = 0; i < USCXML_NUMBER_TRANS; i++) {" << std::endl; + stream << " if (BIT_HAS(i, trans_set) && (USCXML_GET_TRANS(i).type & (USCXML_TRANS_HISTORY | USCXML_TRANS_INITIAL)) == 0) {" << std::endl; + stream << " /* call executable content in transition */" << std::endl; + stream << " if (USCXML_GET_TRANS(i).on_transition != NULL) {" << std::endl; + stream << " if unlikely((err = USCXML_GET_TRANS(i).on_transition(ctx," << std::endl; + stream << " &ctx->machine->states[USCXML_GET_TRANS(i).source]," << std::endl; + stream << " ctx->event)) != USCXML_ERR_OK)" << std::endl; + stream << " return err;" << std::endl; + stream << " }" << std::endl; + stream << " }" << std::endl; + stream << " }" << std::endl; + stream << std::endl; +#endif + + stream << "/* ---------------------------- */" << std::endl; + stream << "/* TAKE_TRANSITIONS: */" << std::endl; + stream << " i = 0;" << std::endl; + stream << " do" << std::endl; + stream << " :: i < USCXML_NUMBER_TRANS -> {" << std::endl; + stream << " if" << std::endl; + stream << " :: trans_set[i] && " << std::endl; + stream << " !" << _prefix << "transitions[i].type[USCXML_TRANS_HISTORY] && " << std::endl; + stream << " !" << _prefix << "transitions[i].type[USCXML_TRANS_INITIAL] -> {" << std::endl; + stream << " /* Call executable content in normal transition */" << std::endl; + stream << " if" << std::endl; + for (auto i = 0; i < _transitions.size(); i++) { + stream << " :: i == " << toStr(i) << " -> {" << std::endl; + writeExecContent(stream, _transitions[i], 4); + stream << " skip;" << std::endl; + stream << " }" << std::endl; + } + stream << " :: else ->skip;" << std::endl; + stream << " fi" << std::endl; + stream << std::endl; + stream << " }" << std::endl; + stream << " :: else -> skip;" << std::endl; + stream << " fi;" << std::endl; + stream << " i = i + 1;" << std::endl; + stream << " }" << std::endl; + stream << " :: else -> break;" << std::endl; + stream << " od;" << std::endl; + stream << std::endl; + + stream << "#if TRACE_EXECUTION" << std::endl; + stream << "printf(\"Took Transitions\\n\");" << std::endl; + stream << "#endif" << std::endl; + +#if 0 + stream << "/* ENTER_STATES: */" << std::endl; + stream << " for (i = 0; i < USCXML_NUMBER_STATES; i++) {" << std::endl; + stream << " if (BIT_HAS(i, entry_set) && !BIT_HAS(i, ctx->config)) {" << std::endl; + stream << " /* these are no proper states */" << std::endl; + stream << " if unlikely(USCXML_STATE_MASK(USCXML_GET_STATE(i).type) == USCXML_STATE_HISTORY_DEEP ||" << std::endl; + stream << " USCXML_STATE_MASK(USCXML_GET_STATE(i).type) == USCXML_STATE_HISTORY_SHALLOW ||" << std::endl; + stream << " USCXML_STATE_MASK(USCXML_GET_STATE(i).type) == USCXML_STATE_INITIAL)" << std::endl; + stream << " continue;" << std::endl; + stream << std::endl; +#endif + + stream << "/* ---------------------------- */" << std::endl; + stream << "/* ENTER_STATES: */" << std::endl; + stream << " i = 0;" << std::endl; + stream << " do" << std::endl; + stream << " :: i < USCXML_NUMBER_STATES -> {" << std::endl; + stream << " if" << std::endl; + stream << " :: (entry_set[i] &&" << std::endl; + stream << " !" << _prefix << "config[i] && " << std::endl; + stream << " /* these are no proper states */" << std::endl; + stream << " !" << _prefix << "states[i].type[USCXML_STATE_HISTORY_DEEP] && " << std::endl; + stream << " !" << _prefix << "states[i].type[USCXML_STATE_HISTORY_SHALLOW] && " << std::endl; + stream << " !" << _prefix << "states[i].type[USCXML_STATE_INITIAL]" << std::endl; + stream << " ) -> {" << std::endl; + +#if 0 + stream << " BIT_SET_AT(i, ctx->config);" << std::endl; + stream << std::endl; +#endif + + stream << "#if TRACE_EXECUTION" << std::endl; + stream << "printf(\"Entering State %d\\n\", i);" << std::endl; + stream << "#endif" << std::endl; + + stream << " " << _prefix << "config[i] = true;" << std::endl; + stream << std::endl; + + +#if 0 + stream << " /* initialize data */" << std::endl; + stream << " if (!BIT_HAS(i, ctx->initialized_data)) {" << std::endl; + stream << " if unlikely(USCXML_GET_STATE(i).data != NULL && ctx->exec_content_init != NULL) {" << std::endl; + stream << " ctx->exec_content_init(ctx, USCXML_GET_STATE(i).data);" << std::endl; + stream << " }" << std::endl; + stream << " BIT_SET_AT(i, ctx->initialized_data);" << std::endl; + stream << " }" << std::endl; + stream << std::endl; + +#endif + + stream << " if" << std::endl; + stream << " :: !" << _prefix << "initialized_data[i] -> {" << std::endl; + stream << " /* TODO: late data binding not supported yet */" << std::endl; + stream << " " << _prefix << "initialized_data[i] = true;" << std::endl; + stream << " skip" << std::endl; + stream << " }" << std::endl; + stream << " :: else -> skip;" << std::endl; + stream << " fi" << std::endl; + stream << std::endl; + +#if 0 + stream << " if (USCXML_GET_STATE(i).on_entry != NULL) {" << std::endl; + stream << " if unlikely((err = USCXML_GET_STATE(i).on_entry(ctx, &USCXML_GET_STATE(i), ctx->event)) != USCXML_ERR_OK)" << std::endl; + stream << " return err;" << std::endl; + stream << " }" << std::endl; + stream << std::endl; + +#endif + + stream << " /* Process executable content for entering a state */" << std::endl; + stream << " if" << std::endl; + for (auto i = 0; i < _states.size(); i++) { + std::list onentries = DOMUtils::filterChildElements(XML_PREFIX(_states[i]).str() + "onentry" , _states[i]); + if (onentries.size() > 0) { + stream << " :: i == " << toStr(i) << " -> {" << std::endl; + for (auto onentry : onentries) + writeExecContent(stream, onentry, 5); + stream << " }" << std::endl; + } + } + stream << " :: else ->skip;" << std::endl; + stream << " fi" << std::endl; + stream << std::endl; + +#if 0 + stream << " /* take history and initial transitions */" << std::endl; + stream << " for (j = 0; j < USCXML_NUMBER_TRANS; j++) {" << std::endl; + stream << " if unlikely(BIT_HAS(j, trans_set) &&" << std::endl; + stream << " (ctx->machine->transitions[j].type & (USCXML_TRANS_HISTORY | USCXML_TRANS_INITIAL)) &&" << std::endl; + stream << " ctx->machine->states[ctx->machine->transitions[j].source].parent == i) {" << std::endl; + stream << " /* call executable content in transition */" << std::endl; + stream << " if (ctx->machine->transitions[j].on_transition != NULL) {" << std::endl; + stream << " if unlikely((err = ctx->machine->transitions[j].on_transition(ctx," << std::endl; + stream << " &USCXML_GET_STATE(i)," << std::endl; + stream << " ctx->event)) != USCXML_ERR_OK)" << std::endl; + stream << " return err;" << std::endl; + stream << " }" << std::endl; + stream << " }" << std::endl; + stream << " }" << std::endl; + stream << std::endl; + +#endif + + stream << " /* take history and initial transitions */" << std::endl; + stream << " j = 0;" << std::endl; + stream << " do" << std::endl; + stream << " :: j < USCXML_NUMBER_TRANS -> {" << std::endl; + stream << " if" << std::endl; + stream << " :: (trans_set[j] &&" << std::endl; + stream << " (" << _prefix << "transitions[j].type[USCXML_TRANS_HISTORY] ||" << std::endl; + stream << " " << _prefix << "transitions[j].type[USCXML_TRANS_INITIAL]) && " << std::endl; + stream << " " << _prefix << "states[" << _prefix << "transitions[j].source].parent == i) -> {" << std::endl; + stream << " /* Call executable content in history or initial transition */" << std::endl; + stream << " if" << std::endl; + for (auto i = 0; i < _transitions.size(); i++) { + stream << " :: j == " << toStr(i) << " -> {" << std::endl; + writeExecContent(stream, _transitions[i], 8); + stream << " skip;" << std::endl; + stream << " }" << std::endl; + } + stream << " :: else ->skip;" << std::endl; + stream << " fi" << std::endl; + stream << std::endl; + + stream << " }" << std::endl; + stream << " :: else -> skip;" << std::endl; + stream << " fi" << std::endl; + stream << " j = j + 1;" << std::endl; + stream << " }" << std::endl; + stream << " :: else -> break;" << std::endl; + stream << " od" << std::endl; + + +#if 0 + stream << " /* handle final states */" << std::endl; + stream << " if unlikely(USCXML_STATE_MASK(USCXML_GET_STATE(i).type) == USCXML_STATE_FINAL) {" << std::endl; +#endif + + stream << " /* handle final states */" << std::endl; + stream << " if" << std::endl; + stream << " :: " << _prefix << "states[i].type[USCXML_STATE_FINAL] -> {" << std::endl; + + +#if 0 + stream << " if unlikely(USCXML_GET_STATE(i).ancestors[0] == 0x01) {" << std::endl; + stream << " ctx->flags |= USCXML_CTX_TOP_LEVEL_FINAL;" << std::endl; + stream << " } else {" << std::endl; + stream << " /* raise done event */" << std::endl; + stream << " const uscxml_elem_donedata* donedata = &ctx->machine->donedata[0];" << std::endl; + stream << " while(USCXML_ELEM_DONEDATA_IS_SET(donedata)) {" << std::endl; + stream << " if unlikely(donedata->source == i)" << std::endl; + stream << " break;" << std::endl; + stream << " donedata++;" << std::endl; + stream << " }" << std::endl; + stream << " ctx->raise_done_event(ctx, &ctx->machine->states[USCXML_GET_STATE(i).parent], (USCXML_ELEM_DONEDATA_IS_SET(donedata) ? donedata : NULL));" << std::endl; + stream << " }" << std::endl; +#endif + + stream << " if" << std::endl; + stream << " :: " << _prefix << "states[" << _prefix << "states[i].parent].children[1] -> {" << std::endl; + stream << " " << _prefix << "flags[USCXML_CTX_TOP_LEVEL_FINAL] = true;" << std::endl; + stream << " }" << std::endl; + stream << " :: else -> {" << std::endl; + stream << " /* TODO: raise done event */" << std::endl; + stream << " skip;" << std::endl; + stream << " }" << std::endl; + stream << " fi" << std::endl; + + +#if 0 + stream << std::endl; + stream << " /**" << std::endl; + stream << " * are we the last final state to leave a parallel state?:" << std::endl; + stream << " * 1. Gather all parallel states in our ancestor chain" << std::endl; + stream << " * 2. Find all states for which these parallels are ancestors" << std::endl; + stream << " * 3. Iterate all active final states and remove their ancestors" << std::endl; + stream << " * 4. If a state remains, not all children of a parallel are final" << std::endl; + stream << " */" << std::endl; + stream << " for (j = 0; j < USCXML_NUMBER_STATES; j++) {" << std::endl; + stream << " if unlikely(USCXML_STATE_MASK(ctx->machine->states[j].type) == USCXML_STATE_PARALLEL &&" << std::endl; + stream << " BIT_HAS(j, USCXML_GET_STATE(i).ancestors)) {" << std::endl; + stream << " bit_clear_all(tmp_states, nr_states_bytes);" << std::endl; + stream << " for (k = 0; k < USCXML_NUMBER_STATES; k++) {" << std::endl; + stream << " if unlikely(BIT_HAS(j, ctx->machine->states[k].ancestors) && BIT_HAS(k, ctx->config)) {" << std::endl; + stream << " if (USCXML_STATE_MASK(ctx->machine->states[k].type) == USCXML_STATE_FINAL) {" << std::endl; + stream << " bit_and_not(tmp_states, ctx->machine->states[k].ancestors, nr_states_bytes);" << std::endl; + stream << " } else {" << std::endl; + stream << " BIT_SET_AT(k, tmp_states);" << std::endl; + stream << " }" << std::endl; + stream << " }" << std::endl; + stream << " }" << std::endl; + stream << " if unlikely(!bit_has_any(tmp_states, nr_states_bytes)) {" << std::endl; + stream << " ctx->raise_done_event(ctx, &ctx->machine->states[j], NULL);" << std::endl; + stream << " }" << std::endl; + stream << " }" << std::endl; + stream << " }" << std::endl; + stream << " }" << std::endl; + stream << " }" << std::endl; + stream << " }" << std::endl; + stream << std::endl; + + stream << " return USCXML_ERR_OK;" << std::endl; + stream << "}" << std::endl; + stream << std::endl; + stream << std::endl; +#endif + + stream << " /** TODO:" << std::endl; + stream << " * are we the last final state to leave a parallel state?:" << std::endl; + stream << " * 1. Gather all parallel states in our ancestor chain" << std::endl; + stream << " * 2. Find all states for which these parallels are ancestors" << std::endl; + stream << " * 3. Iterate all active final states and remove their ancestors" << std::endl; + stream << " * 4. If a state remains, not all children of a parallel are final" << std::endl; + stream << " */" << std::endl; + + + stream << " }" << std::endl; + stream << " :: else -> skip;" << std::endl; + stream << " fi" << std::endl; + + stream << "" << std::endl; + + stream << " }" << std::endl; + stream << " :: else -> skip;" << std::endl; + stream << " i = i + 1;" << std::endl; + stream << " fi;" << std::endl; + stream << " }" << std::endl; + stream << " :: else -> break;" << std::endl; + stream << " od;" << std::endl; + stream << std::endl; + + stream << "#if TRACE_EXECUTION" << std::endl; + stream << "printf(\"Done\\n\");" << std::endl; + stream << "#endif" << std::endl; + + stream << "}" << std::endl; + stream << ":: else -> break;" << std::endl; + stream << "od" << std::endl; + + + stream << "} }" << std::endl; + stream << std::endl; + +} + +#if 0 + +void ChartToPromela::writeProgram(std::ostream& stream) { + + _traceTransitions = envVarIsTrue("USCXML_PROMELA_TRANSITION_TRACE"); + _writeTransitionPrintfs = envVarIsTrue("USCXML_PROMELA_TRANSITION_DEBUG"); + + if (!HAS_ATTR(_scxml, "datamodel") || ATTR(_scxml, "datamodel") != "promela") { + LOG(ERROR) << "Can only convert SCXML documents with \"promela\" datamodel"; + return; + } + + if (HAS_ATTR(_scxml, "binding") && ATTR(_scxml, "binding") != "early") { + LOG(ERROR) << "Can only convert for early data bindings"; + return; + } + + // std::cerr << _scxml << std::endl; + + stream << "/* " << (std::string)_baseURL << " */" << std::endl; + stream << std::endl; + + initNodes(); + + for (std::map, ChartToPromela*>::iterator nestedIter = _machines.begin(); nestedIter != _machines.end(); nestedIter++) { + if (nestedIter->second->_start == NULL) { + nestedIter->second->interpret(); + } + nestedIter->second->initNodes(); + } + + writeEvents(stream); + stream << std::endl; + writeStates(stream); + stream << std::endl; + writeStrings(stream); + stream << std::endl; + if (_analyzer->usesInPredicate()) { + writeStateMap(stream); + stream << std::endl; + } + if (_historyMembers.size() > 0) { + writeHistoryArrays(stream); + stream << std::endl; + } + writeTypeDefs(stream); + stream << std::endl; + writeDeclarations(stream); + stream << std::endl; + + for (std::map, ChartToPromela*>::iterator nestedIter = _machines.begin(); nestedIter != _machines.end(); nestedIter++) { + nestedIter->second->writeDeclarations(stream); + stream << std::endl; + } + + stream << std::endl << "/* global inline functions */" << std::endl; + + if (_analyzer->usesComplexEventStruct()) { + stream << "hidden _event_t tmpE;" << std::endl; + } else { + stream << "hidden int tmpE;" << std::endl; + } + stream << "hidden int tmpIndex;" << std::endl; + + +#if NEW_DELAY_RESHUFFLE + if (_analyzer->usesEventField("delay")) { + writeInsertWithDelay(stream); + stream << std::endl; + } +#endif + + if (_analyzer->usesEventField("delay") && _machines.size() > 0) { + writeDetermineShortestDelay(stream); + stream << std::endl; + writeAdvanceTime(stream); + stream << std::endl; + writeRescheduleProcess(stream); + stream << std::endl; + writeScheduleMachines(stream); + stream << std::endl; + } + + { + NodeSet cancels = DOMUtils::filterChildElements(_nsInfo.xmlNSPrefix + "cancel", _scxml, true); + if (cancels.size() > 0) { + writeCancelEvents(stream); + stream << std::endl; + } + } + { + NodeSet invokes = DOMUtils::filterChildElements(_nsInfo.xmlNSPrefix + "invoke", _scxml, true); + if (invokes.size() > 0 && _analyzer->usesEventField("delay")) { + writeRemovePendingEventsFromInvoker(stream); + stream << std::endl; + } + + } + stream << std::endl; + writeEventSources(stream); + stream << std::endl; + writeFSM(stream); + stream << std::endl; + writeMain(stream); + stream << std::endl; + + for (std::map, ChartToPromela*>::iterator nestedIter = _machines.begin(); nestedIter != _machines.end(); nestedIter++) { + nestedIter->second->writeFSM(stream); + stream << std::endl; + } + + // write ltl expression for success + std::stringstream acceptingStates; + std::string seperator; + + for (std::map::iterator stateIter = _activeConf.begin(); stateIter != _activeConf.end(); stateIter++) { + FlatStateIdentifier flatId(stateIter->first); + if (std::find(flatId.getActive().begin(), flatId.getActive().end(), "pass") != flatId.getActive().end()) { + acceptingStates << seperator << _prefix << "s == s" << stateIter->second->activeIndex; + seperator = " || "; + } + } + if (acceptingStates.str().size() > 0) { + stream << "ltl { eventually (" << acceptingStates.str() << ") }" << std::endl; + } +} +#endif + +void ChartToPromela::writeIfBlock(std::ostream& stream, std::list& condChain, size_t indent) { + if (condChain.size() == 0) + return; + + std::string padding; + for (size_t i = 0; i < indent; i++) { + padding += " "; + } + + bool noNext = condChain.size() == 1; + bool nextIsElse = false; + + DOMElement* ifNode = condChain.front(); + condChain.pop_front(); + + if (condChain.size() > 0) { + if (TAGNAME_CAST(condChain.front()) == "else") { + nextIsElse = true; + } + } + + stream << padding << "if" << std::endl; + // we need to nest the elseifs to resolve promela if semantics + stream << padding << ":: (" << ADAPT_SRC(ATTR(ifNode, "cond")) << ") -> {" << std::endl; + + DOMNode* child; + if (TAGNAME(ifNode) == "if") { + child = ifNode->getFirstChild(); + } else { + child = ifNode->getNextSibling(); + } + while(child) { + if (child->getNodeType() == DOMNode::ELEMENT_NODE) { + DOMElement* childElem = static_cast(child); + if (TAGNAME(childElem) == "elseif" || TAGNAME_CAST(childElem) == "else") + break; + writeExecContent(stream, childElem, indent + 1); + } + child = child->getNextSibling(); + } + stream << padding << "}" << std::endl; + stream << padding << ":: else -> "; + + if (nextIsElse) { + child = condChain.front()->getNextSibling(); + stream << "{" << std::endl; + while(child) { + if (child->getNodeType() == DOMNode::ELEMENT_NODE) { + writeExecContent(stream, child, indent + 1); + } + child = child->getNextSibling(); + } + stream << padding << "}" << std::endl; + + } else if (noNext) { + stream << "skip;" << std::endl; + } else { + stream << "{" << std::endl; + writeIfBlock(stream, condChain, indent + 1); + stream << padding << "}" << std::endl; + } + + stream << padding << "fi;" << std::endl; + +} + +std::string ChartToPromela::beautifyIndentation(const std::string& code, size_t indent) { + + std::string padding; + for (size_t i = 0; i < indent; i++) { + padding += " "; + } + + // remove topmost indentation from every line and reindent + std::stringstream beautifiedSS; + + std::string initialIndent; + bool gotIndent = false; + bool isFirstLine = true; + std::stringstream ssLine(code); + std::string line; + + while(std::getline(ssLine, line)) { + size_t firstChar = line.find_first_not_of(" \t\r\n"); + if (firstChar != std::string::npos) { + if (!gotIndent) { + initialIndent = line.substr(0, firstChar); + gotIndent = true; + } + beautifiedSS << (isFirstLine ? "" : "\n") << padding << boost::replace_first_copy(line, initialIndent, ""); + isFirstLine = false; + } + } + + return beautifiedSS.str(); +} + +std::string ChartToPromela::dataToAssignments(const std::string& prefix, const Data& data) { + std::stringstream retVal; + if (data.atom.size() > 0) { + if (data.type == Data::VERBATIM) { + retVal << prefix << " = " << _analyzer.macroForLiteral(data.atom) << ";" << std::endl; + } else { + retVal << prefix << " = " << data.atom << ";" << std::endl; + } + } else if (data.compound.size() > 0) { + for (std::map::const_iterator cIter = data.compound.begin(); cIter != data.compound.end(); cIter++) { + retVal << dataToAssignments(prefix + "." + cIter->first, cIter->second); + } + } else if (data.array.size() > 0) { + size_t index = 0; + for(std::list::const_iterator aIter = data.array.begin(); aIter != data.array.end(); aIter++) { + retVal << dataToAssignments(prefix + "[" + toStr(index) + "]", *aIter); + index++; + } + } + return retVal.str(); +} + +std::string ChartToPromela::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; +} + +std::string ChartToPromela::declForRange(const std::string& identifier, long minValue, long maxValue, bool nativeOnly) { + // return "int " + identifier; // just for testing + + // we know nothing about this type + if (minValue == 0 && maxValue == 0) + return "int " + identifier; + + if (minValue < 0) { + // only short or int for negatives + if (minValue < -32769 || maxValue > 32767) + return "int " + identifier; + return "short " + identifier; + } + + // type is definitely positive + if (nativeOnly) { + if (maxValue > 32767) + return "int " + identifier; + if (maxValue > 255) + return "short " + identifier; + if (maxValue > 1) + return "byte " + identifier; + return "bool " + identifier; + } else { + return "unsigned " + identifier + " : " + toStr(BIT_WIDTH(maxValue)); + } +} + +void ChartToPromela::writeCancelEvents(std::ostream& stream, int indent) { + std::list queues; + queues.push_back("eQ"); + if (_allowEventInterleaving) + queues.push_back("tmpQ"); + + stream << "inline cancelSendId(sendIdentifier, invokerIdentifier) {" << std::endl; + for (auto machine : *_machinesAll) { + for (auto queue : queues) { + stream << " cancelSendIdOnQueue(sendIdentifier, " << machine.second->_prefix << queue << ", invokerIdentifier);" << std::endl; + } + } + stream << "}" << std::endl; + stream << std::endl; + + + stream << "inline cancelSendIdOnQueue(sendIdentifier, queue, invokerIdentifier) {" << std::endl; + stream << " tmpIndex = 0;" << std::endl; + // stream << _analyzer->getTypeReset("tmpE", _analyzer->getType("_event"), " "); + stream << " do" << std::endl; + stream << " :: tmpIndex < len(queue) -> {" << std::endl; + stream << " queue?tmpE;" << std::endl; + stream << " if" << std::endl; + stream << " :: tmpE.invokeid != invokerIdentifier || tmpE.sendid != sendIdentifier || tmpE.delay == 0 -> queue!tmpE;" << std::endl; + stream << " :: else -> skip;" << std::endl; + stream << " fi" << std::endl; + stream << " tmpIndex++;" << std::endl; + stream << " }" << std::endl; + stream << " :: else -> break;" << std::endl; + stream << " od" << std::endl; + stream << "}" << std::endl; +} + + +} diff --git a/src/uscxml/transform/ChartToPromela.h b/src/uscxml/transform/ChartToPromela.h new file mode 100644 index 0000000..cfba760 --- /dev/null +++ b/src/uscxml/transform/ChartToPromela.h @@ -0,0 +1,130 @@ +/** + * @file + * @author 2012-2014 Stefan Radomski (stefan.radomski@cs.tu-darmstadt.de) + * @copyright Simplified BSD + * + * @cond + * This program is free software: you can redistribute it and/or modify + * it under the terms of the FreeBSD license as published by the FreeBSD + * project. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * You should have received a copy of the FreeBSD license along with this + * program. If not, see . + * @endcond + */ + +#ifndef CHARTTOPROMELA_H_RP48RFDJ +#define CHARTTOPROMELA_H_RP48RFDJ + +#include "Transformer.h" +#include "ChartToC.h" +#include "uscxml/util/DOM.h" + +#include "promela/PromelaInlines.h" +#include "promela/PromelaCodeAnalyzer.h" + +#include + +namespace uscxml { + +class USCXML_API ChartToPromela : public ChartToC { +public: + virtual ~ChartToPromela(); + static Transformer transform(const Interpreter& other); + + void writeTo(std::ostream& stream); + +protected: + ChartToPromela(const Interpreter& other) : ChartToC(other) { + _prefix = "U" + _md5.substr(0, 8) + "_"; + } + + void writeTransitions(std::ostream& stream); + void writeStates(std::ostream& stream); + void writeTypeDefs(std::ostream& stream); + void writeTypes(std::ostream& stream); + void writeMacros(std::ostream& stream); + void writeHelpers(std::ostream& stream); + void writeFSM(std::ostream& stream); + void writeExecContent(std::ostream& stream, const XERCESC_NS::DOMNode* node, size_t indent = 0); + void writeStrings(std::ostream& stream); + + void writeCancelEvents(std::ostream& stream, int indent = 0); + + void prepare(); + + void bit_clear_all(std::ostream& stream, + const std::string& identifier, + size_t length, + size_t indent = 0); + + void bit_copy(std::ostream& stream, + const std::string& from, + const std::string& to, + size_t length, + size_t indent = 0); + + void bit_or(std::ostream& stream, + const std::string& to, + const std::string& mask, + size_t length, + size_t indent = 0); + + void bit_and(std::ostream& stream, + const std::string& to, + const std::string& mask, + size_t length, + size_t indent = 0); + + void bit_and_not(std::ostream& stream, + const std::string& to, + const std::string& mask, + size_t length, + size_t indent = 0); + + void bit_has_and(std::ostream& stream, + const std::string& a, + const std::string& b, + size_t length, + size_t indent = 0); + + void printBitArray(std::ostream& stream, + const std::string& array, + size_t length, + size_t indent = 0); + + PromelaCodeAnalyzer _analyzer; + + ChartToPromela* _parentTopMost; + ChartToPromela* _parent; + std::string _invokerid; + + size_t _internalQueueLength = 7; + size_t _externalQueueLength = 7; + bool _allowEventInterleaving = false; + + std::map _machinesPerId; + std::map* _machinesAllPerId = NULL; + std::map _machines; + std::map* _machinesAll = NULL; + + std::set _dataModelVars; + std::list _varInitializers; // pending initializations for arrays + + std::string beautifyIndentation(const std::string& code, size_t indent = 0); + void writeIfBlock(std::ostream& stream, std::list& condChain, size_t indent = 0); + + std::string dataToAssignments(const std::string& prefix, const Data& data); + std::string sanitizeCode(const std::string& code); + std::string declForRange(const std::string& identifier, long minValue, long maxValue, bool nativeOnly = false); + + friend class PromelaCodeAnalyzer; +}; + +} + +#endif /* end of include guard: CHARTTOPROMELA_H_RP48RFDJ */ diff --git a/src/uscxml/transform/ChartToVHDL.cpp b/src/uscxml/transform/ChartToVHDL.cpp index 37fa03c..13e8120 100644 --- a/src/uscxml/transform/ChartToVHDL.cpp +++ b/src/uscxml/transform/ChartToVHDL.cpp @@ -40,9 +40,9 @@ namespace uscxml { using namespace XERCESC_NS; Transformer ChartToVHDL::transform(const Interpreter& other) { - ChartToVHDL* c2c = new ChartToVHDL(other); + ChartToVHDL* c2c = new ChartToVHDL(other); - return std::shared_ptr(c2c); + return std::shared_ptr(c2c); } ChartToVHDL::ChartToVHDL(const Interpreter& other) : ChartToC(other), _eventTrie(".") { @@ -52,1383 +52,1383 @@ ChartToVHDL::~ChartToVHDL() { } void ChartToVHDL::checkDocument() { - // filter unsupported stuff - std::list unsupported; - unsupported = DOMUtils::inDocumentOrder({ - XML_PREFIX(_scxml).str() + "datamodel", - XML_PREFIX(_scxml).str() + "data", - XML_PREFIX(_scxml).str() + "assign", - XML_PREFIX(_scxml).str() + "donedata", - XML_PREFIX(_scxml).str() + "content", - XML_PREFIX(_scxml).str() + "param", - XML_PREFIX(_scxml).str() + "script", - XML_PREFIX(_scxml).str() + "parallel", - XML_PREFIX(_scxml).str() + "history", - XML_PREFIX(_scxml).str() + "if", - XML_PREFIX(_scxml).str() + "foreach", - XML_PREFIX(_scxml).str() + "send", - XML_PREFIX(_scxml).str() + "cancel", - XML_PREFIX(_scxml).str() + "invoke", - XML_PREFIX(_scxml).str() + "finalize" - }, _scxml); - - std::stringstream ss; - if (unsupported.size() > 0) { - for (auto elem : unsupported) { - ss << " " << DOMUtils::xPathForNode(elem) << " unsupported" << std::endl; - } - throw std::runtime_error("Unsupported elements found:\n" + ss.str()); - } - - unsupported = DOMUtils::inDocumentOrder({ XML_PREFIX(_scxml).str() + "transition" }, _scxml); - - for (auto transition : unsupported) { - if (HAS_ATTR(transition, "cond")) { - ERROR_PLATFORM_THROW("transition with conditions not supported!"); - } - if (!HAS_ATTR(transition, "target")) { - ERROR_PLATFORM_THROW("targetless transition not supported!"); - } - } + // filter unsupported stuff + std::list unsupported; + unsupported = DOMUtils::inDocumentOrder({ + XML_PREFIX(_scxml).str() + "datamodel", + XML_PREFIX(_scxml).str() + "data", + XML_PREFIX(_scxml).str() + "assign", + XML_PREFIX(_scxml).str() + "donedata", + XML_PREFIX(_scxml).str() + "content", + XML_PREFIX(_scxml).str() + "param", + XML_PREFIX(_scxml).str() + "script", + XML_PREFIX(_scxml).str() + "parallel", + XML_PREFIX(_scxml).str() + "history", + XML_PREFIX(_scxml).str() + "if", + XML_PREFIX(_scxml).str() + "foreach", + XML_PREFIX(_scxml).str() + "send", + XML_PREFIX(_scxml).str() + "cancel", + XML_PREFIX(_scxml).str() + "invoke", + XML_PREFIX(_scxml).str() + "finalize" + }, _scxml); + + std::stringstream ss; + if (unsupported.size() > 0) { + for (auto elem : unsupported) { + ss << " " << DOMUtils::xPathForNode(elem) << " unsupported" << std::endl; + } + throw std::runtime_error("Unsupported elements found:\n" + ss.str()); + } + + unsupported = DOMUtils::inDocumentOrder({ XML_PREFIX(_scxml).str() + "transition" }, _scxml); + + for (auto transition : unsupported) { + if (HAS_ATTR(transition, "cond")) { + ERROR_PLATFORM_THROW("transition with conditions not supported!"); + } + if (!HAS_ATTR(transition, "target")) { + ERROR_PLATFORM_THROW("targetless transition not supported!"); + } + } } std::string ChartToVHDL::eventNameEscape(const std::string& eventName) { - std::string escaped = escape(eventName); - boost::replace_all(escaped, ".", "_"); - return escaped; + std::string escaped = escape(eventName); + boost::replace_all(escaped, ".", "_"); + return escaped; } void ChartToVHDL::findEvents() { - // elements with an event attribute - std::list withEvents = DOMUtils::inDocumentOrder({ - XML_PREFIX(_scxml).str() + "raise", - XML_PREFIX(_scxml).str() + "send", - XML_PREFIX(_scxml).str() + "transition", - - }, _scxml); - - for (auto withEvent : withEvents) { - if (HAS_ATTR_CAST(withEvent, "event")) { - // TODO: tokenize! - if (ATTR_CAST(withEvent, "event") != "*") - _eventTrie.addWord(ATTR_CAST(withEvent, "event")); - } - } - - _execContent = DOMUtils::inDocumentOrder({ - XML_PREFIX(_scxml).str() + "raise", - XML_PREFIX(_scxml).str() + "send" - }, _scxml); + // elements with an event attribute + std::list withEvents = DOMUtils::inDocumentOrder({ + XML_PREFIX(_scxml).str() + "raise", + XML_PREFIX(_scxml).str() + "send", + XML_PREFIX(_scxml).str() + "transition", + + }, _scxml); + + for (auto withEvent : withEvents) { + if (HAS_ATTR_CAST(withEvent, "event")) { + // TODO: tokenize! + if (ATTR_CAST(withEvent, "event") != "*") + _eventTrie.addWord(ATTR_CAST(withEvent, "event")); + } + } + + _execContent = DOMUtils::inDocumentOrder({ + XML_PREFIX(_scxml).str() + "raise", + XML_PREFIX(_scxml).str() + "send" + }, _scxml); } void ChartToVHDL::writeTo(std::ostream& stream) { - // same preparations as the C transformation - prepare(); + // same preparations as the C transformation + prepare(); - // checkDocument(); - findEvents(); + // checkDocument(); + findEvents(); - stream << "-- generated from " << std::string(_baseURL) << std::endl; - stream << "-- run as " << std::endl; - stream << "-- ghdl --clean && ghdl -a foo.vhdl && ghdl -e tb && ./tb --stop-time=10ms --vcd=foo.vcd" << std::endl; - stream << std::endl; + stream << "-- generated from " << std::string(_baseURL) << std::endl; + stream << "-- run as " << std::endl; + stream << "-- ghdl --clean && ghdl -a foo.vhdl && ghdl -e tb && ./tb --stop-time=10ms --vcd=foo.vcd" << std::endl; + stream << std::endl; - writeTypes(stream); - writeFiFo(stream); - writeEventController(stream); - writeMicroStepper(stream); - writeTestbench(stream); + writeTypes(stream); + writeFiFo(stream); + writeEventController(stream); + writeMicroStepper(stream); + writeTestbench(stream); } void ChartToVHDL::writeTypes(std::ostream & stream) { - std::string seperator; - - stream << "-- required global types" << std::endl; - stream << "library IEEE;" << std::endl; - stream << "use IEEE.std_logic_1164.all;" << std::endl; - stream << std::endl; - stream << "package machine" << _md5 << " is" << std::endl; - // create state type - stream << " subtype state_type is std_logic_vector( "; - stream << _states.size() - 1; - stream << " downto 0);" << std::endl; - - std::list eventNames = _eventTrie.getWordsWithPrefix(""); - stream << " type event_type is ( hwe_null, "; - seperator = ""; - - for (std::list::iterator eventIter = eventNames.begin(); eventIter != eventNames.end(); eventIter++) { - stream << seperator << "hwe_" << eventNameEscape((*eventIter)->value); - seperator = ", "; - } - stream << " );" << std::endl; - - stream << "end machine" << _md5 << ";" << std::endl; - stream << std::endl; - stream << "-- END needed global types" << std::endl; + std::string seperator; + + stream << "-- required global types" << std::endl; + stream << "library IEEE;" << std::endl; + stream << "use IEEE.std_logic_1164.all;" << std::endl; + stream << std::endl; + stream << "package machine" << _md5 << " is" << std::endl; + // create state type + stream << " subtype state_type is std_logic_vector( "; + stream << _states.size() - 1; + stream << " downto 0);" << std::endl; + + std::list eventNames = _eventTrie.getWordsWithPrefix(""); + stream << " type event_type is ( hwe_null, "; + seperator = ""; + + for (std::list::iterator eventIter = eventNames.begin(); eventIter != eventNames.end(); eventIter++) { + stream << seperator << "hwe_" << eventNameEscape((*eventIter)->value); + seperator = ", "; + } + stream << " );" << std::endl; + + stream << "end machine" << _md5 << ";" << std::endl; + stream << std::endl; + stream << "-- END needed global types" << std::endl; } void ChartToVHDL::writeIncludes(std::ostream & stream) { - // Add controler specific stuff here - stream << "library IEEE;" << std::endl; - stream << "use IEEE.std_logic_1164.all;" << std::endl; - stream << "use work.machine" << _md5 << ".all;" << std::endl; - stream << std::endl; + // Add controler specific stuff here + stream << "library IEEE;" << std::endl; + stream << "use IEEE.std_logic_1164.all;" << std::endl; + stream << "use work.machine" << _md5 << ".all;" << std::endl; + stream << std::endl; } void ChartToVHDL::writeTestbench(std::ostream& stream) { - stream << "-- TESTBENCH" << std::endl; - writeIncludes(stream); - stream << std::endl; - - stream << "-- empty entity" << std::endl; - stream << "entity tb is" << std::endl; - stream << "end entity tb;" << std::endl; - stream << std::endl; - - stream << "architecture bhv of tb is" << std::endl; - stream << std::endl; - - // modules - stream << " -- Module declaration" << std::endl; - stream << " component micro_stepper is" << std::endl; - stream << " port (" << std::endl; - stream << " --inputs" << std::endl; - stream << " clk :in std_logic;" << std::endl; - stream << " rst_i :in std_logic;" << std::endl; - stream << " en :in std_logic;" << std::endl; - stream << " next_event_i :in event_type;" << std::endl; - stream << " next_event_we_i :in std_logic;" << std::endl; - stream << " --outputs" << std::endl; - stream << " error_o :out std_logic;" << std::endl; - - for (auto state : _states) { - stream << " state_active_" << ATTR(state, "documentOrder") << "_o :out std_logic;" << std::endl; - - if (DOMUtils::filterChildElements(XML_PREFIX(_scxml).str() + "onentry", state).size() > 0) { - stream << " entry_set_" << ATTR(state, "documentOrder") << "_o :out std_logic;" << std::endl; - } - - if (DOMUtils::filterChildElements(XML_PREFIX(_scxml).str() + "onexit", state).size() > 0) { - stream << " exit_set_" << ATTR(state, "documentOrder") << "_o :out std_logic;" << std::endl; - } - } - - for (auto transition : _transitions) { - if (DOMUtils::filterChildType(DOMNode::ELEMENT_NODE, transition).size() > 0) { - stream << " transition_set_" << ATTR(transition, "postFixOrder") << "_o :out std_logic;" - << std::endl; - } - } - - stream << " completed_o :out std_logic" << std::endl; - stream << " );" << std::endl; - stream << " end component;" << std::endl; - stream << std::endl; - - stream << " component event_controller is" << std::endl; - stream << " port(" << std::endl; - stream << " --inputs" << std::endl; - stream << " clk :in std_logic;" << std::endl; - stream << " rst_i :in std_logic;" << std::endl; - - for (auto state : _states) { - stream << " state_active_" << ATTR(state, "documentOrder") - << "_i :in std_logic;" << std::endl; - - if (DOMUtils::filterChildElements(XML_PREFIX(_scxml).str() + "onentry", state).size() > 0) { - stream << " entry_set_" << ATTR(state, "documentOrder") - << "_i :in std_logic;" << std::endl; - } - - if (DOMUtils::filterChildElements(XML_PREFIX(_scxml).str() + "onexit", state).size() > 0) { - stream << " exit_set_" << ATTR(state, "documentOrder") - << "_i :in std_logic;" << std::endl; - } - } - - for (auto transition : _transitions) { - if (DOMUtils::filterChildType(DOMNode::ELEMENT_NODE, transition).size() > 0) { - stream << " transition_set_" << ATTR(transition, "postFixOrder") - << "_i :in std_logic;" << std::endl; - } - } - stream << " --outputs" << std::endl; - stream << " micro_stepper_en_o :out std_logic;" << std::endl; - stream << " event_o :out event_type;" << std::endl; - stream << " event_we_o :out std_logic" << std::endl; - // stream << " done_o :out std_logic" << std::endl; - stream << ");" << std::endl; - stream << "end component; " << std::endl; - - // signals - stream << " -- input" << std::endl; - stream << " signal clk : std_logic := '0';" << std::endl; - stream << " signal reset : std_logic;" << std::endl; - stream << " signal dut_enable : std_logic;" << std::endl; - stream << " signal next_event_we_i : std_logic;" << std::endl; - stream << " signal next_event_i : event_type;" << std::endl; - stream << std::endl; - - stream << " -- output" << std::endl; - stream << " signal error_o, completed_o : std_logic;" << std::endl; - stream << std::endl; - - stream << " -- wiring" << std::endl; - for (auto state : _states) { - stream << " signal state_active_" << ATTR(state, "documentOrder") - << "_sig : std_logic;" << std::endl; - - if (DOMUtils::filterChildElements(XML_PREFIX(_scxml).str() + "onentry", state).size() > 0) { - stream << " signal entry_set_" << ATTR(state, "documentOrder") - << "_sig : std_logic;" << std::endl; - } - - if (DOMUtils::filterChildElements(XML_PREFIX(_scxml).str() + "onexit", state).size() > 0) { - stream << " signal exit_set_" << ATTR(state, "documentOrder") - << "_sig : std_logic;" << std::endl; - } - } - - for (auto transition : _transitions) { - if (DOMUtils::filterChildType(DOMNode::ELEMENT_NODE, transition).size() > 0) { - stream << " signal transition_set_" << ATTR(transition, "postFixOrder") - << "_sig : std_logic;" << std::endl; - } - } - - // wiring - stream << "begin" << std::endl; - stream << " clk <= not clk after 20 ns; -- 25 MHz clock frequency" << std::endl; - stream << " reset <= '1', '0' after 100 ns; -- generates reset signal: --__" << std::endl; - stream << std::endl; - - stream << " -- Module instantiation" << std::endl; - stream << " dut : micro_stepper" << std::endl; - stream << " port map (" << std::endl; - stream << " clk => clk," << std::endl; - stream << " rst_i => reset," << std::endl; - stream << " en => dut_enable," << std::endl; - stream << std::endl; - - stream << " next_event_i => next_event_i," << std::endl; - stream << " next_event_we_i => next_event_we_i," << std::endl; - stream << " error_o => error_o," << std::endl; - - for (auto state : _states) { - stream << " state_active_" << ATTR(state, "documentOrder") - << "_o => state_active_" << ATTR(state, "documentOrder") - << "_sig," << std::endl; - - if (DOMUtils::filterChildElements(XML_PREFIX(_scxml).str() + "onentry", state).size() > 0) { - stream << " entry_set_" << ATTR(state, "documentOrder") - << "_o => entry_set_" << ATTR(state, "documentOrder") - << "_sig," << std::endl; - } - - if (DOMUtils::filterChildElements(XML_PREFIX(_scxml).str() + "onexit", state).size() > 0) { - stream << " exit_set_" << ATTR(state, "documentOrder") - << "_o => exit_set_" << ATTR(state, "documentOrder") - << "_sig," << std::endl; - } - } - - for (auto transition : _transitions) { - if (DOMUtils::filterChildType(DOMNode::ELEMENT_NODE, transition).size() > 0) { - stream << " transition_set_" << ATTR(transition, "postFixOrder") - << "_o => transition_set_" << ATTR(transition, "postFixOrder") - << "_sig," << std::endl; - } - } - - stream << " completed_o => completed_o" << std::endl; - stream << " );" << std::endl; - stream << std::endl; - - stream << " ec : event_controller" << std::endl; - stream << " port map (" << std::endl; - stream << " clk => clk," << std::endl; - stream << " rst_i => reset," << std::endl; - stream << std::endl; - - stream << " event_o => next_event_i," << std::endl; - stream << " event_we_o => next_event_we_i," << std::endl; - - for (auto state : _states) { - stream << " state_active_" << ATTR(state, "documentOrder") - << "_i => state_active_" << ATTR(state, "documentOrder") - << "_sig," << std::endl; - - if (DOMUtils::filterChildElements(XML_PREFIX(_scxml).str() + "onentry", state).size() > 0) { - stream << " entry_set_" << ATTR(state, "documentOrder") - << "_i => entry_set_" << ATTR(state, "documentOrder") - << "_sig," << std::endl; - } - - if (DOMUtils::filterChildElements(XML_PREFIX(_scxml).str() + "onexit", state).size() > 0) { - stream << " exit_set_" << ATTR(state, "documentOrder") - << "_i => exit_set_" << ATTR(state, "documentOrder") - << "_sig," << std::endl; - } - } - - for (auto transition : _transitions) { - if (DOMUtils::filterChildType(DOMNode::ELEMENT_NODE, transition).size() > 0) { - stream << " transition_set_" << ATTR(transition, "postFixOrder") - << "_i => transition_set_" << ATTR(transition, "postFixOrder") - << "_sig," << std::endl; - } - } - - stream << " micro_stepper_en_o => dut_enable" << std::endl; - // stream << " done_o => open" << std::endl; - stream << " );" << std::endl; - stream << std::endl; - - stream << "end architecture;" << std::endl; - stream << "-- END TESTBENCH" << std::endl; + stream << "-- TESTBENCH" << std::endl; + writeIncludes(stream); + stream << std::endl; + + stream << "-- empty entity" << std::endl; + stream << "entity tb is" << std::endl; + stream << "end entity tb;" << std::endl; + stream << std::endl; + + stream << "architecture bhv of tb is" << std::endl; + stream << std::endl; + + // modules + stream << " -- Module declaration" << std::endl; + stream << " component micro_stepper is" << std::endl; + stream << " port (" << std::endl; + stream << " --inputs" << std::endl; + stream << " clk :in std_logic;" << std::endl; + stream << " rst_i :in std_logic;" << std::endl; + stream << " en :in std_logic;" << std::endl; + stream << " next_event_i :in event_type;" << std::endl; + stream << " next_event_we_i :in std_logic;" << std::endl; + stream << " --outputs" << std::endl; + stream << " error_o :out std_logic;" << std::endl; + + for (auto state : _states) { + stream << " state_active_" << ATTR(state, "documentOrder") << "_o :out std_logic;" << std::endl; + + if (DOMUtils::filterChildElements(XML_PREFIX(_scxml).str() + "onentry", state).size() > 0) { + stream << " entry_set_" << ATTR(state, "documentOrder") << "_o :out std_logic;" << std::endl; + } + + if (DOMUtils::filterChildElements(XML_PREFIX(_scxml).str() + "onexit", state).size() > 0) { + stream << " exit_set_" << ATTR(state, "documentOrder") << "_o :out std_logic;" << std::endl; + } + } + + for (auto transition : _transitions) { + if (DOMUtils::filterChildType(DOMNode::ELEMENT_NODE, transition).size() > 0) { + stream << " transition_set_" << ATTR(transition, "postFixOrder") << "_o :out std_logic;" + << std::endl; + } + } + + stream << " completed_o :out std_logic" << std::endl; + stream << " );" << std::endl; + stream << " end component;" << std::endl; + stream << std::endl; + + stream << " component event_controller is" << std::endl; + stream << " port(" << std::endl; + stream << " --inputs" << std::endl; + stream << " clk :in std_logic;" << std::endl; + stream << " rst_i :in std_logic;" << std::endl; + + for (auto state : _states) { + stream << " state_active_" << ATTR(state, "documentOrder") + << "_i :in std_logic;" << std::endl; + + if (DOMUtils::filterChildElements(XML_PREFIX(_scxml).str() + "onentry", state).size() > 0) { + stream << " entry_set_" << ATTR(state, "documentOrder") + << "_i :in std_logic;" << std::endl; + } + + if (DOMUtils::filterChildElements(XML_PREFIX(_scxml).str() + "onexit", state).size() > 0) { + stream << " exit_set_" << ATTR(state, "documentOrder") + << "_i :in std_logic;" << std::endl; + } + } + + for (auto transition : _transitions) { + if (DOMUtils::filterChildType(DOMNode::ELEMENT_NODE, transition).size() > 0) { + stream << " transition_set_" << ATTR(transition, "postFixOrder") + << "_i :in std_logic;" << std::endl; + } + } + stream << " --outputs" << std::endl; + stream << " micro_stepper_en_o :out std_logic;" << std::endl; + stream << " event_o :out event_type;" << std::endl; + stream << " event_we_o :out std_logic" << std::endl; + // stream << " done_o :out std_logic" << std::endl; + stream << ");" << std::endl; + stream << "end component; " << std::endl; + + // signals + stream << " -- input" << std::endl; + stream << " signal clk : std_logic := '0';" << std::endl; + stream << " signal reset : std_logic;" << std::endl; + stream << " signal dut_enable : std_logic;" << std::endl; + stream << " signal next_event_we_i : std_logic;" << std::endl; + stream << " signal next_event_i : event_type;" << std::endl; + stream << std::endl; + + stream << " -- output" << std::endl; + stream << " signal error_o, completed_o : std_logic;" << std::endl; + stream << std::endl; + + stream << " -- wiring" << std::endl; + for (auto state : _states) { + stream << " signal state_active_" << ATTR(state, "documentOrder") + << "_sig : std_logic;" << std::endl; + + if (DOMUtils::filterChildElements(XML_PREFIX(_scxml).str() + "onentry", state).size() > 0) { + stream << " signal entry_set_" << ATTR(state, "documentOrder") + << "_sig : std_logic;" << std::endl; + } + + if (DOMUtils::filterChildElements(XML_PREFIX(_scxml).str() + "onexit", state).size() > 0) { + stream << " signal exit_set_" << ATTR(state, "documentOrder") + << "_sig : std_logic;" << std::endl; + } + } + + for (auto transition : _transitions) { + if (DOMUtils::filterChildType(DOMNode::ELEMENT_NODE, transition).size() > 0) { + stream << " signal transition_set_" << ATTR(transition, "postFixOrder") + << "_sig : std_logic;" << std::endl; + } + } + + // wiring + stream << "begin" << std::endl; + stream << " clk <= not clk after 20 ns; -- 25 MHz clock frequency" << std::endl; + stream << " reset <= '1', '0' after 100 ns; -- generates reset signal: --__" << std::endl; + stream << std::endl; + + stream << " -- Module instantiation" << std::endl; + stream << " dut : micro_stepper" << std::endl; + stream << " port map (" << std::endl; + stream << " clk => clk," << std::endl; + stream << " rst_i => reset," << std::endl; + stream << " en => dut_enable," << std::endl; + stream << std::endl; + + stream << " next_event_i => next_event_i," << std::endl; + stream << " next_event_we_i => next_event_we_i," << std::endl; + stream << " error_o => error_o," << std::endl; + + for (auto state : _states) { + stream << " state_active_" << ATTR(state, "documentOrder") + << "_o => state_active_" << ATTR(state, "documentOrder") + << "_sig," << std::endl; + + if (DOMUtils::filterChildElements(XML_PREFIX(_scxml).str() + "onentry", state).size() > 0) { + stream << " entry_set_" << ATTR(state, "documentOrder") + << "_o => entry_set_" << ATTR(state, "documentOrder") + << "_sig," << std::endl; + } + + if (DOMUtils::filterChildElements(XML_PREFIX(_scxml).str() + "onexit", state).size() > 0) { + stream << " exit_set_" << ATTR(state, "documentOrder") + << "_o => exit_set_" << ATTR(state, "documentOrder") + << "_sig," << std::endl; + } + } + + for (auto transition : _transitions) { + if (DOMUtils::filterChildType(DOMNode::ELEMENT_NODE, transition).size() > 0) { + stream << " transition_set_" << ATTR(transition, "postFixOrder") + << "_o => transition_set_" << ATTR(transition, "postFixOrder") + << "_sig," << std::endl; + } + } + + stream << " completed_o => completed_o" << std::endl; + stream << " );" << std::endl; + stream << std::endl; + + stream << " ec : event_controller" << std::endl; + stream << " port map (" << std::endl; + stream << " clk => clk," << std::endl; + stream << " rst_i => reset," << std::endl; + stream << std::endl; + + stream << " event_o => next_event_i," << std::endl; + stream << " event_we_o => next_event_we_i," << std::endl; + + for (auto state : _states) { + stream << " state_active_" << ATTR(state, "documentOrder") + << "_i => state_active_" << ATTR(state, "documentOrder") + << "_sig," << std::endl; + + if (DOMUtils::filterChildElements(XML_PREFIX(_scxml).str() + "onentry", state).size() > 0) { + stream << " entry_set_" << ATTR(state, "documentOrder") + << "_i => entry_set_" << ATTR(state, "documentOrder") + << "_sig," << std::endl; + } + + if (DOMUtils::filterChildElements(XML_PREFIX(_scxml).str() + "onexit", state).size() > 0) { + stream << " exit_set_" << ATTR(state, "documentOrder") + << "_i => exit_set_" << ATTR(state, "documentOrder") + << "_sig," << std::endl; + } + } + + for (auto transition : _transitions) { + if (DOMUtils::filterChildType(DOMNode::ELEMENT_NODE, transition).size() > 0) { + stream << " transition_set_" << ATTR(transition, "postFixOrder") + << "_i => transition_set_" << ATTR(transition, "postFixOrder") + << "_sig," << std::endl; + } + } + + stream << " micro_stepper_en_o => dut_enable" << std::endl; + // stream << " done_o => open" << std::endl; + stream << " );" << std::endl; + stream << std::endl; + + stream << "end architecture;" << std::endl; + stream << "-- END TESTBENCH" << std::endl; } void ChartToVHDL::writeExContentBlock(std::ostream & stream, - std::string index, std::list< DOMElement* > commandSequence) { - // index should be [entry, transition, exit]__ + std::string index, std::list< DOMElement* > commandSequence) { + // index should be [entry, transition, exit]__ - // write clock blocks + // write clock blocks } void ChartToVHDL::writeEventController(std::ostream & stream) { - // Add controler specific stuff here - // create hardware top level - stream << "-- Event Controller Logic" << std::endl; - writeIncludes(stream); - stream << "entity event_controller is" << std::endl; - stream << "port(" << std::endl; - stream << " --inputs" << std::endl; - stream << " clk :in std_logic;" << std::endl; - stream << " rst_i :in std_logic;" << std::endl; - - for (auto state : _states) { - stream << " state_active_" << ATTR(state, "documentOrder") - << "_i :in std_logic;" << std::endl; - - if (DOMUtils::filterChildElements(XML_PREFIX(_scxml).str() + "onentry", state).size() > 0) { - stream << " entry_set_" << ATTR(state, "documentOrder") - << "_i :in std_logic;" << std::endl; - } - - if (DOMUtils::filterChildElements(XML_PREFIX(_scxml).str() + "onexit", state).size() > 0) { - stream << " exit_set_" << ATTR(state, "documentOrder") - << "_i :in std_logic;" << std::endl; - } - } - - for (auto transition : _transitions) { - if (DOMUtils::filterChildType(DOMNode::ELEMENT_NODE, transition).size() > 0) { - stream << " transition_set_" << ATTR(transition, "postFixOrder") - << "_i :in std_logic;" << std::endl; - } - } - - stream << " --outputs" << std::endl; - stream << " micro_stepper_en_o :out std_logic;" << std::endl; - stream << " event_o :out event_type;" << std::endl; - stream << " event_we_o :out std_logic" << std::endl; - stream << ");" << std::endl; - stream << "end event_controller; " << std::endl; - - stream << std::endl; - stream << "architecture behavioral of event_controller is " << std::endl; - stream << std::endl; - - // Add signals and components - stream << "signal rst : std_logic;" << std::endl; - stream << "signal micro_stepper_en : std_logic;" << std::endl; - stream << "signal cmpl_buf : std_logic;" << std::endl; - stream << "signal completed_sig : std_logic;" << std::endl; - stream << "signal event_bus : event_type;" << std::endl; - stream << "signal event_we : std_logic;" << std::endl; - - for (int i = 0; i < _execContent.size(); i++) { - stream << "signal done_" << toStr(i) << "_sig : std_logic;" << std::endl; - stream << "signal start_" << toStr(i) << "_sig : std_logic;" << std::endl; - } - - stream << "-- sequence input line" << std::endl; - for (int i = 0; i < _execContent.size(); i++) { - stream << "signal seq_" << toStr(i) << "_sig : std_logic;" << std::endl; - } - stream << std::endl; - - stream << "begin" << std::endl; - stream << std::endl; - // system signal mapping - stream << "rst <= rst_i;" << std::endl; - stream << "micro_stepper_en_o <= micro_stepper_en;" << std::endl; - stream << "event_o <= event_bus;" << std::endl; - stream << "event_we_o <= event_we;" << std::endl; - stream << std::endl; - - // stall management - stream << "-- stalling microstepper" << std::endl; - // stream << "ms_enable_manager : process (clk, rst) " << std::endl; - // stream << "begin" << std::endl; - // stream << " if rst = '1' then" << std::endl; - // stream << " micro_stepper_en <= '1';" << std::endl; - // stream << " elsif rising_edge(clk) then" << std::endl; - // stream << " " << std::endl; - stream << "micro_stepper_en <= completed_sig or not ( '0' "; - for (auto state : _states) { - - if (DOMUtils::filterChildElements(XML_PREFIX(_scxml).str() + "onentry", state).size() > 0) { - stream << std::endl << " or entry_set_" << ATTR(state, "documentOrder") - << "_i"; - } - - if (DOMUtils::filterChildElements(XML_PREFIX(_scxml).str() + "onexit", state).size() > 0) { - stream << std::endl << " or exit_set_" << ATTR(state, "documentOrder") - << "_i"; - } - } - for (auto transition : _transitions) { - if (DOMUtils::filterChildType(DOMNode::ELEMENT_NODE, transition).size() > 0) { - stream << std::endl << " or transition_set_" << ATTR(transition, "postFixOrder") - << "_i"; - } - } - stream << ");" << std::endl; - // stream << " end if;" << std::endl; - // stream << "end process;" << std::endl; - stream << std::endl; - - // write enable management - // stream << "-- write enable for FIFO buffer" << std::endl; - // stream << "event_we <= not rst and ('0'"; - // for (int i = 0; i < _execContent.size(); i++) { - // stream << std::endl << " or start_" << toStr(i) << "_sig"; - // } - // stream << ");" << std::endl; - // stream << std::endl; - - // sequential code operation - stream << "-- seq code block " << std::endl; - stream << "ex_content_block : process (clk, rst) " << std::endl; - stream << "begin" << std::endl; - stream << " if rst = '1' then" << std::endl; - for (int i = 0; i < _execContent.size(); i++) { - stream << " done_" << toStr(i) << "_sig <= '0';" << std::endl; - } - stream << " event_bus <= hwe_null;" << std::endl; - stream << " event_we <= '0';" << std::endl; - stream << " cmpl_buf <= '0';" << std::endl; - stream << " completed_sig <= '0';" << std::endl; - stream << " elsif rising_edge(clk) then" << std::endl; - - stream << " if micro_stepper_en = '1' then" << std::endl; - stream << " cmpl_buf <= '0' ;" << std::endl; - stream << " else" << std::endl; - stream << " cmpl_buf <= seq_" << toStr(_execContent.size() - 1) - << "_sig;" << std::endl; - stream << " end if;" << std::endl; - stream << " completed_sig <= cmpl_buf;" << std::endl << std::endl; - - size_t i = 0; - std::string seperator; - for (auto ecIter = _execContent.begin(); ecIter != _execContent.end(); ecIter++, i++) { - DOMElement* exContentElem = *ecIter; - - //TODO if raise - if (TAGNAME(exContentElem) == XML_PREFIX(_scxml).str() + "raise" || - TAGNAME(exContentElem) == XML_PREFIX(_scxml).str() + "send") { - stream << seperator << "if start_" << toStr(i) << "_sig = '1' then" - << std::endl; - //TODO use escape - stream << " event_bus <= hwe_" << ATTR(exContentElem, "event") - << ";" << std::endl; - stream << " done_" << toStr(i) << "_sig <= '1';" << std::endl; - stream << " event_we <= '1';" << std::endl; - seperator = " els"; - } - } - stream << " elsif micro_stepper_en = '1' then" << std::endl; - for (auto exContentElem : _execContent) { - - //TODO if raise - if (TAGNAME(exContentElem) == XML_PREFIX(_scxml).str() + "raise") { - stream << " done_" << toStr(i) << "_sig <= '0';" << std::endl; - } - } - stream << " event_we <= '0';" << std::endl; - stream << " end if;" << std::endl; - stream << " end if;" << std::endl; - stream << "end process;" << std::endl; - stream << std::endl; - - i = 0; - for (auto ecIter = _execContent.begin(); ecIter != _execContent.end(); ecIter++, i++) { - // start lines - stream << "start_" << toStr(i) << "_sig <= " - << getLineForExecContent(*ecIter) << " and " - << "not done_" << toStr(i) << "_sig"; - if (i != 0) { // if not first element - stream << " and seq_" << toStr(i) << "_sig"; - } - stream << ";" << std::endl; - - } - - stream << "seq_0_sig <= '1';" << std::endl; - - if (_execContent.size() > 1) { - i = 0; - for (auto ecIter = _execContent.begin(); ecIter != _execContent.end(); ecIter++, i++) { - // seq lines (input if process i is in seqence now) - stream << "seq_" << toStr(i) << "_sig <= " - << "done_" << toStr(i - 1) << "_sig or " - << "( not " - << getLineForExecContent(*ecIter); - stream << " and seq_" << toStr(i - 1) << "_sig"; - stream << " );" << std::endl; - } - } - stream << std::endl; - - stream << "end behavioral; " << std::endl; - stream << "-- END Event Controller Logic" << std::endl; + // Add controler specific stuff here + // create hardware top level + stream << "-- Event Controller Logic" << std::endl; + writeIncludes(stream); + stream << "entity event_controller is" << std::endl; + stream << "port(" << std::endl; + stream << " --inputs" << std::endl; + stream << " clk :in std_logic;" << std::endl; + stream << " rst_i :in std_logic;" << std::endl; + + for (auto state : _states) { + stream << " state_active_" << ATTR(state, "documentOrder") + << "_i :in std_logic;" << std::endl; + + if (DOMUtils::filterChildElements(XML_PREFIX(_scxml).str() + "onentry", state).size() > 0) { + stream << " entry_set_" << ATTR(state, "documentOrder") + << "_i :in std_logic;" << std::endl; + } + + if (DOMUtils::filterChildElements(XML_PREFIX(_scxml).str() + "onexit", state).size() > 0) { + stream << " exit_set_" << ATTR(state, "documentOrder") + << "_i :in std_logic;" << std::endl; + } + } + + for (auto transition : _transitions) { + if (DOMUtils::filterChildType(DOMNode::ELEMENT_NODE, transition).size() > 0) { + stream << " transition_set_" << ATTR(transition, "postFixOrder") + << "_i :in std_logic;" << std::endl; + } + } + + stream << " --outputs" << std::endl; + stream << " micro_stepper_en_o :out std_logic;" << std::endl; + stream << " event_o :out event_type;" << std::endl; + stream << " event_we_o :out std_logic" << std::endl; + stream << ");" << std::endl; + stream << "end event_controller; " << std::endl; + + stream << std::endl; + stream << "architecture behavioral of event_controller is " << std::endl; + stream << std::endl; + + // Add signals and components + stream << "signal rst : std_logic;" << std::endl; + stream << "signal micro_stepper_en : std_logic;" << std::endl; + stream << "signal cmpl_buf : std_logic;" << std::endl; + stream << "signal completed_sig : std_logic;" << std::endl; + stream << "signal event_bus : event_type;" << std::endl; + stream << "signal event_we : std_logic;" << std::endl; + + for (int i = 0; i < _execContent.size(); i++) { + stream << "signal done_" << toStr(i) << "_sig : std_logic;" << std::endl; + stream << "signal start_" << toStr(i) << "_sig : std_logic;" << std::endl; + } + + stream << "-- sequence input line" << std::endl; + for (int i = 0; i < _execContent.size(); i++) { + stream << "signal seq_" << toStr(i) << "_sig : std_logic;" << std::endl; + } + stream << std::endl; + + stream << "begin" << std::endl; + stream << std::endl; + // system signal mapping + stream << "rst <= rst_i;" << std::endl; + stream << "micro_stepper_en_o <= micro_stepper_en;" << std::endl; + stream << "event_o <= event_bus;" << std::endl; + stream << "event_we_o <= event_we;" << std::endl; + stream << std::endl; + + // stall management + stream << "-- stalling microstepper" << std::endl; + // stream << "ms_enable_manager : process (clk, rst) " << std::endl; + // stream << "begin" << std::endl; + // stream << " if rst = '1' then" << std::endl; + // stream << " micro_stepper_en <= '1';" << std::endl; + // stream << " elsif rising_edge(clk) then" << std::endl; + // stream << " " << std::endl; + stream << "micro_stepper_en <= completed_sig or not ( '0' "; + for (auto state : _states) { + + if (DOMUtils::filterChildElements(XML_PREFIX(_scxml).str() + "onentry", state).size() > 0) { + stream << std::endl << " or entry_set_" << ATTR(state, "documentOrder") + << "_i"; + } + + if (DOMUtils::filterChildElements(XML_PREFIX(_scxml).str() + "onexit", state).size() > 0) { + stream << std::endl << " or exit_set_" << ATTR(state, "documentOrder") + << "_i"; + } + } + for (auto transition : _transitions) { + if (DOMUtils::filterChildType(DOMNode::ELEMENT_NODE, transition).size() > 0) { + stream << std::endl << " or transition_set_" << ATTR(transition, "postFixOrder") + << "_i"; + } + } + stream << ");" << std::endl; + // stream << " end if;" << std::endl; + // stream << "end process;" << std::endl; + stream << std::endl; + + // write enable management + // stream << "-- write enable for FIFO buffer" << std::endl; + // stream << "event_we <= not rst and ('0'"; + // for (int i = 0; i < _execContent.size(); i++) { + // stream << std::endl << " or start_" << toStr(i) << "_sig"; + // } + // stream << ");" << std::endl; + // stream << std::endl; + + // sequential code operation + stream << "-- seq code block " << std::endl; + stream << "ex_content_block : process (clk, rst) " << std::endl; + stream << "begin" << std::endl; + stream << " if rst = '1' then" << std::endl; + for (int i = 0; i < _execContent.size(); i++) { + stream << " done_" << toStr(i) << "_sig <= '0';" << std::endl; + } + stream << " event_bus <= hwe_null;" << std::endl; + stream << " event_we <= '0';" << std::endl; + stream << " cmpl_buf <= '0';" << std::endl; + stream << " completed_sig <= '0';" << std::endl; + stream << " elsif rising_edge(clk) then" << std::endl; + + stream << " if micro_stepper_en = '1' then" << std::endl; + stream << " cmpl_buf <= '0' ;" << std::endl; + stream << " else" << std::endl; + stream << " cmpl_buf <= seq_" << toStr(_execContent.size() - 1) + << "_sig;" << std::endl; + stream << " end if;" << std::endl; + stream << " completed_sig <= cmpl_buf;" << std::endl << std::endl; + + size_t i = 0; + std::string seperator; + for (auto ecIter = _execContent.begin(); ecIter != _execContent.end(); ecIter++, i++) { + DOMElement* exContentElem = *ecIter; + + //TODO if raise + if (TAGNAME(exContentElem) == XML_PREFIX(_scxml).str() + "raise" || + TAGNAME(exContentElem) == XML_PREFIX(_scxml).str() + "send") { + stream << seperator << "if start_" << toStr(i) << "_sig = '1' then" + << std::endl; + //TODO use escape + stream << " event_bus <= hwe_" << ATTR(exContentElem, "event") + << ";" << std::endl; + stream << " done_" << toStr(i) << "_sig <= '1';" << std::endl; + stream << " event_we <= '1';" << std::endl; + seperator = " els"; + } + } + stream << " elsif micro_stepper_en = '1' then" << std::endl; + for (auto exContentElem : _execContent) { + + //TODO if raise + if (TAGNAME(exContentElem) == XML_PREFIX(_scxml).str() + "raise") { + stream << " done_" << toStr(i) << "_sig <= '0';" << std::endl; + } + } + stream << " event_we <= '0';" << std::endl; + stream << " end if;" << std::endl; + stream << " end if;" << std::endl; + stream << "end process;" << std::endl; + stream << std::endl; + + i = 0; + for (auto ecIter = _execContent.begin(); ecIter != _execContent.end(); ecIter++, i++) { + // start lines + stream << "start_" << toStr(i) << "_sig <= " + << getLineForExecContent(*ecIter) << " and " + << "not done_" << toStr(i) << "_sig"; + if (i != 0) { // if not first element + stream << " and seq_" << toStr(i) << "_sig"; + } + stream << ";" << std::endl; + + } + + stream << "seq_0_sig <= '1';" << std::endl; + + if (_execContent.size() > 1) { + i = 0; + for (auto ecIter = _execContent.begin(); ecIter != _execContent.end(); ecIter++, i++) { + // seq lines (input if process i is in seqence now) + stream << "seq_" << toStr(i) << "_sig <= " + << "done_" << toStr(i - 1) << "_sig or " + << "( not " + << getLineForExecContent(*ecIter); + stream << " and seq_" << toStr(i - 1) << "_sig"; + stream << " );" << std::endl; + } + } + stream << std::endl; + + stream << "end behavioral; " << std::endl; + stream << "-- END Event Controller Logic" << std::endl; } std::string ChartToVHDL::getLineForExecContent(const DOMNode* elem) { - const DOMNode* ecBlock = elem; - while (ecBlock) { - if (ecBlock->getNodeType() == DOMNode::ELEMENT_NODE) { - std::string localName = LOCALNAME_CAST(ecBlock); - if (localName == XML_PREFIX(_scxml).str() + "transition") { - return "transition_set_" + ATTR_CAST(ecBlock, "postFixOrder") + "_i"; - } - - if (localName == XML_PREFIX(_scxml).str() + "onentry") { - return "entry_set_" + ATTR_CAST(ecBlock->getParentNode(), "documentOrder") + "_i"; - } - - if (localName == XML_PREFIX(_scxml).str() + "onexit") { - return "exit_set_" + ATTR_CAST(ecBlock->getParentNode(), "documentOrder") + "_i"; - } - - } - ecBlock = ecBlock->getParentNode(); - } - - return ""; + const DOMNode* ecBlock = elem; + while (ecBlock) { + if (ecBlock->getNodeType() == DOMNode::ELEMENT_NODE) { + std::string localName = LOCALNAME_CAST(ecBlock); + if (localName == XML_PREFIX(_scxml).str() + "transition") { + return "transition_set_" + ATTR_CAST(ecBlock, "postFixOrder") + "_i"; + } + + if (localName == XML_PREFIX(_scxml).str() + "onentry") { + return "entry_set_" + ATTR_CAST(ecBlock->getParentNode(), "documentOrder") + "_i"; + } + + if (localName == XML_PREFIX(_scxml).str() + "onexit") { + return "exit_set_" + ATTR_CAST(ecBlock->getParentNode(), "documentOrder") + "_i"; + } + + } + ecBlock = ecBlock->getParentNode(); + } + + return ""; } void ChartToVHDL::writeMicroStepper(std::ostream & stream) { - // create MicroStepper top level - stream << "-- FSM Logic" << std::endl; - writeIncludes(stream); - stream << "entity micro_stepper is" << std::endl; - stream << "port(" << std::endl; - stream << " --inputs" << std::endl; - stream << " clk :in std_logic;" << std::endl; - stream << " rst_i :in std_logic;" << std::endl; - stream << " en :in std_logic;" << std::endl; - stream << " next_event_i :in event_type;" << std::endl; - stream << " next_event_we_i :in std_logic;" << std::endl; - stream << " --outputs" << std::endl; - stream << " error_o :out std_logic;" << std::endl; - - for (auto state : _states) { - stream << " state_active_" << ATTR(state, "documentOrder") << "_o :out std_logic;" << std::endl; - - if (DOMUtils::filterChildElements(XML_PREFIX(_scxml).str() + "onentry", state).size() > 0) { - stream << " entry_set_" << ATTR(state, "documentOrder") << "_o :out std_logic;" << std::endl; - } - - if (DOMUtils::filterChildElements(XML_PREFIX(_scxml).str() + "onexit", state).size() > 0) { - stream << " exit_set_" << ATTR(state, "documentOrder") << "_o :out std_logic;" << std::endl; - } - } - - for (auto transition : _transitions) { - if (DOMUtils::filterChildType(DOMNode::ELEMENT_NODE, transition).size() > 0) { - stream << " transition_set_" << ATTR(transition, "postFixOrder") << "_o :out std_logic;" - << std::endl; - } - } - - stream << " completed_o :out std_logic" << std::endl; - stream << ");" << std::endl; - stream << "end micro_stepper; " << std::endl; - - stream << std::endl; - stream << "architecture behavioral of micro_stepper is " << std::endl; - stream << std::endl; - - // Add signals and components - writeSignalsAndComponents(stream); - - stream << std::endl; - stream << "begin" << std::endl; - stream << std::endl; - - // signal mapping - writeModuleInstantiation(stream); - - // signal handler - writeSpontaneousHandler(stream); - writeErrorHandler(stream); - writeInternalEventHandler(stream); - writeStateHandler(stream); - writeResetHandler(stream); - - // combinatorial logic for Sn+1 - writeOptimalTransitionSetSelection(stream); - writeExitSet(stream); - writeCompleteEntrySet(stream); - writeEntrySet(stream); - writeDefaultCompletions(stream); - writeActiveStateNplusOne(stream); - - // connect output signals - writeSystemSignalMapping(stream); - - - stream << std::endl; - stream << "end behavioral; " << std::endl; - stream << "-- END FSM Logic" << std::endl; + // create MicroStepper top level + stream << "-- FSM Logic" << std::endl; + writeIncludes(stream); + stream << "entity micro_stepper is" << std::endl; + stream << "port(" << std::endl; + stream << " --inputs" << std::endl; + stream << " clk :in std_logic;" << std::endl; + stream << " rst_i :in std_logic;" << std::endl; + stream << " en :in std_logic;" << std::endl; + stream << " next_event_i :in event_type;" << std::endl; + stream << " next_event_we_i :in std_logic;" << std::endl; + stream << " --outputs" << std::endl; + stream << " error_o :out std_logic;" << std::endl; + + for (auto state : _states) { + stream << " state_active_" << ATTR(state, "documentOrder") << "_o :out std_logic;" << std::endl; + + if (DOMUtils::filterChildElements(XML_PREFIX(_scxml).str() + "onentry", state).size() > 0) { + stream << " entry_set_" << ATTR(state, "documentOrder") << "_o :out std_logic;" << std::endl; + } + + if (DOMUtils::filterChildElements(XML_PREFIX(_scxml).str() + "onexit", state).size() > 0) { + stream << " exit_set_" << ATTR(state, "documentOrder") << "_o :out std_logic;" << std::endl; + } + } + + for (auto transition : _transitions) { + if (DOMUtils::filterChildType(DOMNode::ELEMENT_NODE, transition).size() > 0) { + stream << " transition_set_" << ATTR(transition, "postFixOrder") << "_o :out std_logic;" + << std::endl; + } + } + + stream << " completed_o :out std_logic" << std::endl; + stream << ");" << std::endl; + stream << "end micro_stepper; " << std::endl; + + stream << std::endl; + stream << "architecture behavioral of micro_stepper is " << std::endl; + stream << std::endl; + + // Add signals and components + writeSignalsAndComponents(stream); + + stream << std::endl; + stream << "begin" << std::endl; + stream << std::endl; + + // signal mapping + writeModuleInstantiation(stream); + + // signal handler + writeSpontaneousHandler(stream); + writeErrorHandler(stream); + writeInternalEventHandler(stream); + writeStateHandler(stream); + writeResetHandler(stream); + + // combinatorial logic for Sn+1 + writeOptimalTransitionSetSelection(stream); + writeExitSet(stream); + writeCompleteEntrySet(stream); + writeEntrySet(stream); + writeDefaultCompletions(stream); + writeActiveStateNplusOne(stream); + + // connect output signals + writeSystemSignalMapping(stream); + + + stream << std::endl; + stream << "end behavioral; " << std::endl; + stream << "-- END FSM Logic" << std::endl; } void ChartToVHDL::writeFiFo(std::ostream & stream) { - // taken from: http://www.deathbylogic.com/2013/07/vhdl-standard-fifo/ - // alternativly take fifo logic for a ram device: http://www.eng.auburn.edu/~strouce/class/elec4200/vhdlmods.pdf - stream << "-- standard FIFO buffer" << std::endl; - writeIncludes(stream); - stream << "" << std::endl; - stream << "entity std_fifo is" << std::endl; - stream << "generic (" << std::endl; - stream << " constant FIFO_DEPTH : positive := 256" << std::endl; - stream << ");" << std::endl; - stream << "port ( " << std::endl; - stream << " clk : in std_logic;" << std::endl; - stream << " rst : in std_logic;" << std::endl; - stream << " write_en : in std_logic;" << std::endl; - stream << " read_en : in std_logic;" << std::endl; - stream << " data_in : in event_type;" << std::endl; - stream << " data_out : out event_type;" << std::endl; - stream << " empty : out std_logic;" << std::endl; - stream << " full : out std_logic" << std::endl; - stream << ");" << std::endl; - stream << "end std_fifo;" << std::endl; - stream << "" << std::endl; - stream << "architecture behavioral of std_fifo is" << std::endl; - stream << "begin" << std::endl; - stream << "-- Memory Pointer Process" << std::endl; - stream << "fifo_proc : process (clk)" << std::endl; - stream << " type FIFO_Memory is array (0 to FIFO_DEPTH - 1) of event_type;" << std::endl; - stream << " variable Memory : FIFO_Memory;" << std::endl; - stream << "" << std::endl; - stream << " variable Head : natural range 0 to FIFO_DEPTH - 1;" << std::endl; - stream << " variable Tail : natural range 0 to FIFO_DEPTH - 1;" << std::endl; - stream << "" << std::endl; - stream << " variable Looped : boolean;" << std::endl; - stream << "begin" << std::endl; - stream << " if rising_edge(clk) then" << std::endl; - stream << " if rst = '1' then" << std::endl; - stream << " Head := 0;" << std::endl; - stream << " Tail := 0;" << std::endl; - stream << "" << std::endl; - stream << " Looped := false;" << std::endl; - stream << "" << std::endl; - stream << " full <= '0';" << std::endl; - stream << " empty <= '1';" << std::endl; - stream << " else" << std::endl; - stream << " if (read_en = '1') then" << std::endl; - stream << " if ((Looped = true) or (Head /= Tail)) then" << std::endl; - stream << " -- Update data output" << std::endl; - stream << " data_out <= Memory(Tail);" << std::endl; - stream << " " << std::endl; - stream << " -- Update Tail pointer as needed" << std::endl; - stream << " if (Tail = FIFO_DEPTH - 1) then" << std::endl; - stream << " Tail := 0;" << std::endl; - stream << " " << std::endl; - stream << " Looped := false;" << std::endl; - stream << " else" << std::endl; - stream << " Tail := Tail + 1;" << std::endl; - stream << " end if;" << std::endl; - stream << "" << std::endl; - stream << " end if;" << std::endl; - stream << " end if;" << std::endl; - stream << "" << std::endl; - stream << " if (write_en = '1') then" << std::endl; - stream << " if ((Looped = false) or (Head /= Tail)) then" << std::endl; - stream << " -- Write Data to Memory" << std::endl; - stream << " Memory(Head) := data_in;" << std::endl; - stream << " " << std::endl; - stream << " -- Increment Head pointer as needed" << std::endl; - stream << " if (Head = FIFO_DEPTH - 1) then" << std::endl; - stream << " Head := 0;" << std::endl; - stream << " " << std::endl; - stream << " Looped := true;" << std::endl; - stream << " else" << std::endl; - stream << " Head := Head + 1;" << std::endl; - stream << " end if;" << std::endl; - stream << " end if;" << std::endl; - stream << " end if;" << std::endl; - stream << "" << std::endl; - stream << " -- Update empty and full flags" << std::endl; - stream << " if (Head = Tail) then" << std::endl; - stream << " if Looped then" << std::endl; - stream << " full <= '1';" << std::endl; - stream << " else" << std::endl; - stream << " empty <= '1';" << std::endl; - stream << " end if;" << std::endl; - stream << " else" << std::endl; - stream << " empty <= '0';" << std::endl; - stream << " full <= '0';" << std::endl; - stream << " end if;" << std::endl; - stream << " end if;" << std::endl; - stream << " end if;" << std::endl; - stream << "end process;" << std::endl; - stream << "" << std::endl; - stream << "end behavioral;" << std::endl; - stream << "-- END standard FIFO buffer" << std::endl; + // taken from: http://www.deathbylogic.com/2013/07/vhdl-standard-fifo/ + // alternativly take fifo logic for a ram device: http://www.eng.auburn.edu/~strouce/class/elec4200/vhdlmods.pdf + stream << "-- standard FIFO buffer" << std::endl; + writeIncludes(stream); + stream << "" << std::endl; + stream << "entity std_fifo is" << std::endl; + stream << "generic (" << std::endl; + stream << " constant FIFO_DEPTH : positive := 256" << std::endl; + stream << ");" << std::endl; + stream << "port ( " << std::endl; + stream << " clk : in std_logic;" << std::endl; + stream << " rst : in std_logic;" << std::endl; + stream << " write_en : in std_logic;" << std::endl; + stream << " read_en : in std_logic;" << std::endl; + stream << " data_in : in event_type;" << std::endl; + stream << " data_out : out event_type;" << std::endl; + stream << " empty : out std_logic;" << std::endl; + stream << " full : out std_logic" << std::endl; + stream << ");" << std::endl; + stream << "end std_fifo;" << std::endl; + stream << "" << std::endl; + stream << "architecture behavioral of std_fifo is" << std::endl; + stream << "begin" << std::endl; + stream << "-- Memory Pointer Process" << std::endl; + stream << "fifo_proc : process (clk)" << std::endl; + stream << " type FIFO_Memory is array (0 to FIFO_DEPTH - 1) of event_type;" << std::endl; + stream << " variable Memory : FIFO_Memory;" << std::endl; + stream << "" << std::endl; + stream << " variable Head : natural range 0 to FIFO_DEPTH - 1;" << std::endl; + stream << " variable Tail : natural range 0 to FIFO_DEPTH - 1;" << std::endl; + stream << "" << std::endl; + stream << " variable Looped : boolean;" << std::endl; + stream << "begin" << std::endl; + stream << " if rising_edge(clk) then" << std::endl; + stream << " if rst = '1' then" << std::endl; + stream << " Head := 0;" << std::endl; + stream << " Tail := 0;" << std::endl; + stream << "" << std::endl; + stream << " Looped := false;" << std::endl; + stream << "" << std::endl; + stream << " full <= '0';" << std::endl; + stream << " empty <= '1';" << std::endl; + stream << " else" << std::endl; + stream << " if (read_en = '1') then" << std::endl; + stream << " if ((Looped = true) or (Head /= Tail)) then" << std::endl; + stream << " -- Update data output" << std::endl; + stream << " data_out <= Memory(Tail);" << std::endl; + stream << " " << std::endl; + stream << " -- Update Tail pointer as needed" << std::endl; + stream << " if (Tail = FIFO_DEPTH - 1) then" << std::endl; + stream << " Tail := 0;" << std::endl; + stream << " " << std::endl; + stream << " Looped := false;" << std::endl; + stream << " else" << std::endl; + stream << " Tail := Tail + 1;" << std::endl; + stream << " end if;" << std::endl; + stream << "" << std::endl; + stream << " end if;" << std::endl; + stream << " end if;" << std::endl; + stream << "" << std::endl; + stream << " if (write_en = '1') then" << std::endl; + stream << " if ((Looped = false) or (Head /= Tail)) then" << std::endl; + stream << " -- Write Data to Memory" << std::endl; + stream << " Memory(Head) := data_in;" << std::endl; + stream << " " << std::endl; + stream << " -- Increment Head pointer as needed" << std::endl; + stream << " if (Head = FIFO_DEPTH - 1) then" << std::endl; + stream << " Head := 0;" << std::endl; + stream << " " << std::endl; + stream << " Looped := true;" << std::endl; + stream << " else" << std::endl; + stream << " Head := Head + 1;" << std::endl; + stream << " end if;" << std::endl; + stream << " end if;" << std::endl; + stream << " end if;" << std::endl; + stream << "" << std::endl; + stream << " -- Update empty and full flags" << std::endl; + stream << " if (Head = Tail) then" << std::endl; + stream << " if Looped then" << std::endl; + stream << " full <= '1';" << std::endl; + stream << " else" << std::endl; + stream << " empty <= '1';" << std::endl; + stream << " end if;" << std::endl; + stream << " else" << std::endl; + stream << " empty <= '0';" << std::endl; + stream << " full <= '0';" << std::endl; + stream << " end if;" << std::endl; + stream << " end if;" << std::endl; + stream << " end if;" << std::endl; + stream << "end process;" << std::endl; + stream << "" << std::endl; + stream << "end behavioral;" << std::endl; + stream << "-- END standard FIFO buffer" << std::endl; } void ChartToVHDL::writeSignalsAndComponents(std::ostream & stream) { - // create internal signals - stream << "-- system signals" << std::endl; - stream << "signal stall : std_logic;" << std::endl; - stream << "signal completed_sig : std_logic;" << std::endl; - // stream << "signal rst_2 : std_logic;" << std::endl; - // stream << "signal rst_1 : std_logic;" << std::endl; - stream << "signal rst : std_logic;" << std::endl; - stream << std::endl; - - stream << "-- state signals" << std::endl; - - std::list signalDecls; - - for (auto state : _states) { - - signalDecls.push_back("signal state_active_" + ATTR(state, "documentOrder") + "_sig : std_logic;"); - signalDecls.push_back("signal state_next_" + ATTR(state, "documentOrder") + "_sig : std_logic;"); - signalDecls.push_back("signal in_entry_set_" + ATTR(state, "documentOrder") + "_sig : std_logic;"); - signalDecls.push_back("signal in_exit_set_" + ATTR(state, "documentOrder") + "_sig : std_logic;"); - signalDecls.push_back("signal in_complete_entry_set_up_" + ATTR(state, "documentOrder") + "_sig : std_logic;"); - signalDecls.push_back("signal in_complete_entry_set_" + ATTR(state, "documentOrder") + "_sig : std_logic;"); - signalDecls.push_back("signal default_completion_" + ATTR(state, "documentOrder") + "_sig : std_logic;"); - } - - signalDecls.sort(); - for (std::list::iterator iter = signalDecls.begin(); iter != signalDecls.end(); iter++) { - stream << *iter << std::endl; - } - stream << std::endl; - - - stream << "-- transition signals" << std::endl; - stream << "signal spontaneous_en : std_logic;" << std::endl; - stream << "signal spontaneous_active : std_logic;" << std::endl; - stream << "signal optimal_transition_set_combined_sig : std_logic;" << std::endl; - - for (auto transition : _transitions) { - stream << "signal in_optimal_transition_set_" << ATTR(transition, "postFixOrder") << "_sig : std_logic;" - << std::endl; - } - stream << std::endl; - - stream << "-- event signals" << std::endl; - stream << "signal int_event_write_en : std_logic;" << std::endl; - stream << "signal int_event_read_en : std_logic;" << std::endl; - stream << "signal int_event_empty : std_logic;" << std::endl; - stream << "signal int_event_input : event_type;" << std::endl; - stream << "signal int_event_output : event_type;" << std::endl; - stream << "signal next_event_re : std_logic;" << std::endl; - stream << "signal next_event_dequeued : std_logic;" << std::endl; - stream << "signal next_event : event_type;" << std::endl; - stream << "signal event_consumed : std_logic;" << std::endl; - stream << std::endl; - - std::list eventNames = _eventTrie.getWordsWithPrefix(""); - for (std::list::iterator eventIter = eventNames.begin(); eventIter != eventNames.end(); eventIter++) { - stream << "signal event_" << eventNameEscape((*eventIter)->value) << "_sig : std_logic;" << std::endl; - } - stream << std::endl; - - stream << "-- error signals" << std::endl; - stream << "signal reg_error_out : std_logic;" << std::endl; - stream << "signal error_full_int_event_fifo : std_logic;" << std::endl; - stream << std::endl; - - // add components - stream << "-- event FIFO" << std::endl; - stream << "component std_fifo is" << std::endl; - stream << "port ( " << std::endl; - stream << " clk : in std_logic;" << std::endl; - stream << " rst : in std_logic;" << std::endl; - stream << " write_en : in std_logic;" << std::endl; - stream << " read_en : in std_logic;" << std::endl; - stream << " data_in : in event_type;" << std::endl; - stream << " data_out : out event_type;" << std::endl; - stream << " empty : out std_logic;" << std::endl; - stream << " full : out std_logic" << std::endl; // we calculate how much we need - stream << ");" << std::endl; - stream << "end component;" << std::endl; - stream << std::endl; + // create internal signals + stream << "-- system signals" << std::endl; + stream << "signal stall : std_logic;" << std::endl; + stream << "signal completed_sig : std_logic;" << std::endl; + // stream << "signal rst_2 : std_logic;" << std::endl; + // stream << "signal rst_1 : std_logic;" << std::endl; + stream << "signal rst : std_logic;" << std::endl; + stream << std::endl; + + stream << "-- state signals" << std::endl; + + std::list signalDecls; + + for (auto state : _states) { + + signalDecls.push_back("signal state_active_" + ATTR(state, "documentOrder") + "_sig : std_logic;"); + signalDecls.push_back("signal state_next_" + ATTR(state, "documentOrder") + "_sig : std_logic;"); + signalDecls.push_back("signal in_entry_set_" + ATTR(state, "documentOrder") + "_sig : std_logic;"); + signalDecls.push_back("signal in_exit_set_" + ATTR(state, "documentOrder") + "_sig : std_logic;"); + signalDecls.push_back("signal in_complete_entry_set_up_" + ATTR(state, "documentOrder") + "_sig : std_logic;"); + signalDecls.push_back("signal in_complete_entry_set_" + ATTR(state, "documentOrder") + "_sig : std_logic;"); + signalDecls.push_back("signal default_completion_" + ATTR(state, "documentOrder") + "_sig : std_logic;"); + } + + signalDecls.sort(); + for (std::list::iterator iter = signalDecls.begin(); iter != signalDecls.end(); iter++) { + stream << *iter << std::endl; + } + stream << std::endl; + + + stream << "-- transition signals" << std::endl; + stream << "signal spontaneous_en : std_logic;" << std::endl; + stream << "signal spontaneous_active : std_logic;" << std::endl; + stream << "signal optimal_transition_set_combined_sig : std_logic;" << std::endl; + + for (auto transition : _transitions) { + stream << "signal in_optimal_transition_set_" << ATTR(transition, "postFixOrder") << "_sig : std_logic;" + << std::endl; + } + stream << std::endl; + + stream << "-- event signals" << std::endl; + stream << "signal int_event_write_en : std_logic;" << std::endl; + stream << "signal int_event_read_en : std_logic;" << std::endl; + stream << "signal int_event_empty : std_logic;" << std::endl; + stream << "signal int_event_input : event_type;" << std::endl; + stream << "signal int_event_output : event_type;" << std::endl; + stream << "signal next_event_re : std_logic;" << std::endl; + stream << "signal next_event_dequeued : std_logic;" << std::endl; + stream << "signal next_event : event_type;" << std::endl; + stream << "signal event_consumed : std_logic;" << std::endl; + stream << std::endl; + + std::list eventNames = _eventTrie.getWordsWithPrefix(""); + for (std::list::iterator eventIter = eventNames.begin(); eventIter != eventNames.end(); eventIter++) { + stream << "signal event_" << eventNameEscape((*eventIter)->value) << "_sig : std_logic;" << std::endl; + } + stream << std::endl; + + stream << "-- error signals" << std::endl; + stream << "signal reg_error_out : std_logic;" << std::endl; + stream << "signal error_full_int_event_fifo : std_logic;" << std::endl; + stream << std::endl; + + // add components + stream << "-- event FIFO" << std::endl; + stream << "component std_fifo is" << std::endl; + stream << "port ( " << std::endl; + stream << " clk : in std_logic;" << std::endl; + stream << " rst : in std_logic;" << std::endl; + stream << " write_en : in std_logic;" << std::endl; + stream << " read_en : in std_logic;" << std::endl; + stream << " data_in : in event_type;" << std::endl; + stream << " data_out : out event_type;" << std::endl; + stream << " empty : out std_logic;" << std::endl; + stream << " full : out std_logic" << std::endl; // we calculate how much we need + stream << ");" << std::endl; + stream << "end component;" << std::endl; + stream << std::endl; } void ChartToVHDL::writeModuleInstantiation(std::ostream & stream) { - // instantiate event fifo - stream << "int_event_fifo : component std_fifo " << std::endl; - stream << "port map ( " << std::endl; - stream << " clk => clk," << std::endl; - stream << " rst => rst_i," << std::endl; - stream << " write_en => int_event_write_en," << std::endl; - stream << " read_en => int_event_read_en," << std::endl; - stream << " data_in => int_event_input," << std::endl; - stream << " data_out => int_event_output," << std::endl; - stream << " empty => int_event_empty," << std::endl; - stream << " full => error_full_int_event_fifo" << std::endl; // we calculate how much we need - stream << ");" << std::endl; - stream << std::endl; + // instantiate event fifo + stream << "int_event_fifo : component std_fifo " << std::endl; + stream << "port map ( " << std::endl; + stream << " clk => clk," << std::endl; + stream << " rst => rst_i," << std::endl; + stream << " write_en => int_event_write_en," << std::endl; + stream << " read_en => int_event_read_en," << std::endl; + stream << " data_in => int_event_input," << std::endl; + stream << " data_out => int_event_output," << std::endl; + stream << " empty => int_event_empty," << std::endl; + stream << " full => error_full_int_event_fifo" << std::endl; // we calculate how much we need + stream << ");" << std::endl; + stream << std::endl; } void ChartToVHDL::writeErrorHandler(std::ostream & stream) { - // sets error output signal if an error occures somewhere - stream << "-- error handler" << std::endl; - stream << "-- sets error output signal if an error occures somewhere" << std::endl; - stream << "error_handler : process (clk, rst) " << std::endl; - stream << "begin" << std::endl; - stream << " if rst = '1' then" << std::endl; - stream << " reg_error_out <= '0';" << std::endl; - stream << " elsif rising_edge(clk) then" << std::endl; - stream << " reg_error_out <= error_full_int_event_fifo;" << std::endl; - stream << " end if;" << std::endl; - stream << "end process;" << std::endl; - stream << std::endl; + // sets error output signal if an error occures somewhere + stream << "-- error handler" << std::endl; + stream << "-- sets error output signal if an error occures somewhere" << std::endl; + stream << "error_handler : process (clk, rst) " << std::endl; + stream << "begin" << std::endl; + stream << " if rst = '1' then" << std::endl; + stream << " reg_error_out <= '0';" << std::endl; + stream << " elsif rising_edge(clk) then" << std::endl; + stream << " reg_error_out <= error_full_int_event_fifo;" << std::endl; + stream << " end if;" << std::endl; + stream << "end process;" << std::endl; + stream << std::endl; } void ChartToVHDL::writeResetHandler(std::ostream & stream) { - stream << "-- reset handler" << std::endl; - stream << "rst <= rst_i;" << std::endl; - // stream << "rst_proc: process(clk, rst_i)" << std::endl; - // stream << "begin" << std::endl; - // stream << " if rst_i = '1' then" << std::endl; - // stream << " rst_2 <= '1';" << std::endl; - // stream << " rst_1 <= '1';" << std::endl; - // stream << " rst <= '1';" << std::endl; - // stream << " elsif (rising_edge(clk)) then" << std::endl; - // stream << " rst_2 <= rst_i;" << std::endl; - // stream << " rst_1 <= rst_i;" << std::endl; - // stream << " rst <= rst_1;" << std::endl; - // stream << " end if;" << std::endl; - // stream << "end process;" << std::endl; - stream << std::endl; + stream << "-- reset handler" << std::endl; + stream << "rst <= rst_i;" << std::endl; + // stream << "rst_proc: process(clk, rst_i)" << std::endl; + // stream << "begin" << std::endl; + // stream << " if rst_i = '1' then" << std::endl; + // stream << " rst_2 <= '1';" << std::endl; + // stream << " rst_1 <= '1';" << std::endl; + // stream << " rst <= '1';" << std::endl; + // stream << " elsif (rising_edge(clk)) then" << std::endl; + // stream << " rst_2 <= rst_i;" << std::endl; + // stream << " rst_1 <= rst_i;" << std::endl; + // stream << " rst <= rst_1;" << std::endl; + // stream << " end if;" << std::endl; + // stream << "end process;" << std::endl; + stream << std::endl; } void ChartToVHDL::writeSpontaneousHandler(std::ostream & stream) { - // sets spontaneous signal - stream << "-- spontaneous handler" << std::endl; - stream << "spontaneous_handler : process (clk, rst) " << std::endl; - stream << "begin" << std::endl; - stream << " if rst = '1' then" << std::endl; - stream << " spontaneous_en <= '1';" << std::endl; - stream << " elsif rising_edge(clk) and stall = '0' then" << std::endl; - stream << " if spontaneous_en = '1' then" << std::endl; - stream << " spontaneous_en <= optimal_transition_set_combined_sig;" << std::endl; - stream << " else" << std::endl; - //TODO if new event is dequeued then 1 else stay 0 - stream << " spontaneous_en <= next_event_dequeued;" << std::endl; - stream << " end if;" << std::endl; - stream << " end if;" << std::endl; - stream << "end process;" << std::endl; - stream << std::endl; + // sets spontaneous signal + stream << "-- spontaneous handler" << std::endl; + stream << "spontaneous_handler : process (clk, rst) " << std::endl; + stream << "begin" << std::endl; + stream << " if rst = '1' then" << std::endl; + stream << " spontaneous_en <= '1';" << std::endl; + stream << " elsif rising_edge(clk) and stall = '0' then" << std::endl; + stream << " if spontaneous_en = '1' then" << std::endl; + stream << " spontaneous_en <= optimal_transition_set_combined_sig;" << std::endl; + stream << " else" << std::endl; + //TODO if new event is dequeued then 1 else stay 0 + stream << " spontaneous_en <= next_event_dequeued;" << std::endl; + stream << " end if;" << std::endl; + stream << " end if;" << std::endl; + stream << "end process;" << std::endl; + stream << std::endl; } void ChartToVHDL::writeInternalEventHandler(std::ostream & stream) { - // Add controler specific stuff here - stream << "-- event handler" << std::endl; - stream << "-- pops events and set event signals" << std::endl; - stream << "event_handler : process (clk, rst) " << std::endl; - stream << "begin" << std::endl; - stream << " if rst = '1' then" << std::endl; - - std::list eventNames = _eventTrie.getWordsWithPrefix(""); - for (std::list::iterator eventIter = eventNames.begin(); eventIter != eventNames.end(); eventIter++) { - stream << " event_" << eventNameEscape((*eventIter)->value) << "_sig <= '0';" << std::endl; - } - - stream << " next_event_dequeued <= '0';" << std::endl; - stream << " event_consumed <= '0';" << std::endl; - - stream << " elsif falling_edge(clk) and stall = '0' then" << std::endl; - - VContainer eventConsumed = VOR; - for (auto transition : _transitions) { - - if (HAS_ATTR(transition, "event") == true) { - *eventConsumed += VLINE("in_optimal_transition_set_" - + ATTR(transition, "postFixOrder") + "_sig"); - } - } - - VBranch* tree = (VASSIGN, - VLINE("event_consumed"), - eventConsumed); - tree->print(stream); - stream << ";" << std::endl; - - stream << " if int_event_empty = '0' then " << std::endl; - stream << " case next_event is " << std::endl; - for (std::list::iterator eventIter = eventNames.begin(); eventIter != eventNames.end(); eventIter++) { - stream << " when hwe_" - << eventNameEscape((*eventIter)->value) << " =>" << std::endl; - for (std::list::iterator eventIter2 = eventNames.begin(); eventIter2 != eventNames.end(); eventIter2++) { - stream << " event_" << eventNameEscape((*eventIter2)->value); - if (eventNameEscape((*eventIter)->value) == eventNameEscape((*eventIter2)->value)) { - stream << "_sig <= '1';" << std::endl; - } else { - stream << "_sig <= '0';" << std::endl; - } - } - stream << " next_event_dequeued <= '1';" << std::endl; - } - stream << " when others =>" << std::endl; - for (std::list::iterator eventIter = eventNames.begin(); eventIter != eventNames.end(); eventIter++) { - stream << " event_" << eventNameEscape((*eventIter)->value) << "_sig <= '0';" << std::endl; - } - stream << " next_event_dequeued <= '0';" << std::endl; - stream << " end case;" << std::endl; - stream << " elsif int_event_empty = '1' and event_consumed = '1' then" << std::endl; - - for (std::list::iterator eventIter = eventNames.begin(); eventIter != eventNames.end(); eventIter++) { - stream << " event_" << eventNameEscape((*eventIter)->value) << "_sig <= '0';" << std::endl; - } - stream << " next_event_dequeued <= '0';" << std::endl; - stream << " end if;" << std::endl; - stream << " end if;" << std::endl; - stream << "end process;" << std::endl; - stream << std::endl; - - stream << "next_event_re <= not int_event_empty and not stall; " << std::endl; - stream << "next_event <= int_event_output; " << std::endl; - stream << "int_event_write_en <= next_event_we_i; " << std::endl; - stream << "int_event_input <= next_event_i; " << std::endl; - stream << "int_event_read_en <= not stall; --not spontaneous_en and " << std::endl; - stream << std::endl; + // Add controler specific stuff here + stream << "-- event handler" << std::endl; + stream << "-- pops events and set event signals" << std::endl; + stream << "event_handler : process (clk, rst) " << std::endl; + stream << "begin" << std::endl; + stream << " if rst = '1' then" << std::endl; + + std::list eventNames = _eventTrie.getWordsWithPrefix(""); + for (std::list::iterator eventIter = eventNames.begin(); eventIter != eventNames.end(); eventIter++) { + stream << " event_" << eventNameEscape((*eventIter)->value) << "_sig <= '0';" << std::endl; + } + + stream << " next_event_dequeued <= '0';" << std::endl; + stream << " event_consumed <= '0';" << std::endl; + + stream << " elsif falling_edge(clk) and stall = '0' then" << std::endl; + + VContainer eventConsumed = VOR; + for (auto transition : _transitions) { + + if (HAS_ATTR(transition, "event") == true) { + *eventConsumed += VLINE("in_optimal_transition_set_" + + ATTR(transition, "postFixOrder") + "_sig"); + } + } + + VBranch* tree = (VASSIGN, + VLINE("event_consumed"), + eventConsumed); + tree->print(stream); + stream << ";" << std::endl; + + stream << " if int_event_empty = '0' then " << std::endl; + stream << " case next_event is " << std::endl; + for (std::list::iterator eventIter = eventNames.begin(); eventIter != eventNames.end(); eventIter++) { + stream << " when hwe_" + << eventNameEscape((*eventIter)->value) << " =>" << std::endl; + for (std::list::iterator eventIter2 = eventNames.begin(); eventIter2 != eventNames.end(); eventIter2++) { + stream << " event_" << eventNameEscape((*eventIter2)->value); + if (eventNameEscape((*eventIter)->value) == eventNameEscape((*eventIter2)->value)) { + stream << "_sig <= '1';" << std::endl; + } else { + stream << "_sig <= '0';" << std::endl; + } + } + stream << " next_event_dequeued <= '1';" << std::endl; + } + stream << " when others =>" << std::endl; + for (std::list::iterator eventIter = eventNames.begin(); eventIter != eventNames.end(); eventIter++) { + stream << " event_" << eventNameEscape((*eventIter)->value) << "_sig <= '0';" << std::endl; + } + stream << " next_event_dequeued <= '0';" << std::endl; + stream << " end case;" << std::endl; + stream << " elsif int_event_empty = '1' and event_consumed = '1' then" << std::endl; + + for (std::list::iterator eventIter = eventNames.begin(); eventIter != eventNames.end(); eventIter++) { + stream << " event_" << eventNameEscape((*eventIter)->value) << "_sig <= '0';" << std::endl; + } + stream << " next_event_dequeued <= '0';" << std::endl; + stream << " end if;" << std::endl; + stream << " end if;" << std::endl; + stream << "end process;" << std::endl; + stream << std::endl; + + stream << "next_event_re <= not int_event_empty and not stall; " << std::endl; + stream << "next_event <= int_event_output; " << std::endl; + stream << "int_event_write_en <= next_event_we_i; " << std::endl; + stream << "int_event_input <= next_event_i; " << std::endl; + stream << "int_event_read_en <= not stall; --not spontaneous_en and " << std::endl; + stream << std::endl; } void ChartToVHDL::writeActiveStateNplusOne(std::ostream & stream) { - stream << "-- active configuration" << std::endl; + stream << "-- active configuration" << std::endl; - size_t i = 0; - for (auto stateIter = _states.begin(); stateIter != _states.end(); stateIter++, i++) { + size_t i = 0; + for (auto stateIter = _states.begin(); stateIter != _states.end(); stateIter++, i++) { // DOMElement* state = *stateIter; - // TÖDO: is there a case where complete entry set reflects not the next state ? - VBranch* tree = (VASSIGN, - VLINE("state_next_" + toStr(i) + "_sig"), - (VOR, - VLINE("in_complete_entry_set_" + toStr(i) + "_sig"), - (VAND, (VNOT, VLINE("in_exit_set_" + toStr(i) + "_sig")), VLINE("state_active_" + toStr(i) + "_sig")) - ) ); - - tree->print(stream); - stream << ";" << std::endl; - - } + // TÖDO: is there a case where complete entry set reflects not the next state ? + VBranch* tree = (VASSIGN, + VLINE("state_next_" + toStr(i) + "_sig"), + (VOR, + VLINE("in_complete_entry_set_" + toStr(i) + "_sig"), + (VAND, (VNOT, VLINE("in_exit_set_" + toStr(i) + "_sig")), VLINE("state_active_" + toStr(i) + "_sig")) + ) ); + + tree->print(stream); + stream << ";" << std::endl; + + } } void ChartToVHDL::writeOptimalTransitionSetSelection(std::ostream & stream) { - stream << "-- optimal transition set selection" << std::endl; - VContainer optimalTransitions = VOR; - VContainer spontaneoursActive = VOR; - size_t i = 0; - for (auto transIter = _transitions.begin(); transIter != _transitions.end(); transIter++, i++) { - DOMElement* transition = *transIter; - std::string conflicts = ATTR(transition, "conflictBools"); - - - VContainer nameMatchers = VOR; - if (HAS_ATTR(transition, "event")) { - std::list eventDescs = tokenize(ATTR(transition, "event")); - for (std::list::iterator descIter = eventDescs.begin(); descIter != eventDescs.end(); descIter++) { - std::list eventNames = _eventTrie.getWordsWithPrefix((*descIter) == "*" ? "" : *descIter); - for (std::list::iterator eventIter = eventNames.begin(); eventIter != eventNames.end(); eventIter++) { - *nameMatchers += VLINE("event_" + eventNameEscape((*eventIter)->value) + "_sig"); - } - } - } else { - *nameMatchers += VLINE("'1'"); - } - - VContainer conflicters = VOR; - for (size_t j = 0; j < i; j++) { - if (conflicts[j] == '1') { - *conflicters += VLINE("in_optimal_transition_set_" + toStr(j) + "_sig"); - } - } - - VBranch* tree = (VASSIGN, - VLINE("in_optimal_transition_set_" + ATTR(transition, "postFixOrder") + "_sig"), - (VAND, - (HAS_ATTR(transition, "event") - ? (VNOT, VLINE("spontaneous_active")) - : (VNOP, VLINE("spontaneous_en"))), - VLINE("state_active_" + ATTR(transition, "source") + "_sig"), - nameMatchers, - (VNOT, conflicters))); - - tree->print(stream); - stream << ";" << std::endl; - - *optimalTransitions += VLINE("in_optimal_transition_set_" - + ATTR(transition, "postFixOrder") + "_sig"); - if (HAS_ATTR(transition, "event") == false) { - *spontaneoursActive += VLINE("in_optimal_transition_set_" - + ATTR(transition, "postFixOrder") + "_sig"); - } - } - - VBranch* tree = (VASSIGN, - VLINE("optimal_transition_set_combined_sig"), - optimalTransitions); - tree->print(stream); - stream << ";" << std::endl; - - VBranch* tree2 = (VASSIGN, - VLINE("spontaneous_active"), - spontaneoursActive); - tree2->print(stream); - stream << ";" << std::endl; + stream << "-- optimal transition set selection" << std::endl; + VContainer optimalTransitions = VOR; + VContainer spontaneoursActive = VOR; + size_t i = 0; + for (auto transIter = _transitions.begin(); transIter != _transitions.end(); transIter++, i++) { + DOMElement* transition = *transIter; + std::string conflicts = ATTR(transition, "conflictBools"); + + + VContainer nameMatchers = VOR; + if (HAS_ATTR(transition, "event")) { + std::list eventDescs = tokenize(ATTR(transition, "event")); + for (std::list::iterator descIter = eventDescs.begin(); descIter != eventDescs.end(); descIter++) { + std::list eventNames = _eventTrie.getWordsWithPrefix((*descIter) == "*" ? "" : *descIter); + for (std::list::iterator eventIter = eventNames.begin(); eventIter != eventNames.end(); eventIter++) { + *nameMatchers += VLINE("event_" + eventNameEscape((*eventIter)->value) + "_sig"); + } + } + } else { + *nameMatchers += VLINE("'1'"); + } + + VContainer conflicters = VOR; + for (size_t j = 0; j < i; j++) { + if (conflicts[j] == '1') { + *conflicters += VLINE("in_optimal_transition_set_" + toStr(j) + "_sig"); + } + } + + VBranch* tree = (VASSIGN, + VLINE("in_optimal_transition_set_" + ATTR(transition, "postFixOrder") + "_sig"), + (VAND, + (HAS_ATTR(transition, "event") + ? (VNOT, VLINE("spontaneous_active")) + : (VNOP, VLINE("spontaneous_en"))), + VLINE("state_active_" + ATTR(transition, "source") + "_sig"), + nameMatchers, + (VNOT, conflicters))); + + tree->print(stream); + stream << ";" << std::endl; + + *optimalTransitions += VLINE("in_optimal_transition_set_" + + ATTR(transition, "postFixOrder") + "_sig"); + if (HAS_ATTR(transition, "event") == false) { + *spontaneoursActive += VLINE("in_optimal_transition_set_" + + ATTR(transition, "postFixOrder") + "_sig"); + } + } + + VBranch* tree = (VASSIGN, + VLINE("optimal_transition_set_combined_sig"), + optimalTransitions); + tree->print(stream); + stream << ";" << std::endl; + + VBranch* tree2 = (VASSIGN, + VLINE("spontaneous_active"), + spontaneoursActive); + tree2->print(stream); + stream << ";" << std::endl; } void ChartToVHDL::writeExitSet(std::ostream & stream) { - stream << "-- exit set selection" << std::endl; - - size_t i = 0; - for (auto stateIter = _states.begin(); stateIter != _states.end(); stateIter++, i++) { - DOMElement* state = *stateIter; - - std::string completion = ATTR(state, "completionBools"); - std::string ancestors = ATTR(state, "ancBools"); - std::string children = ATTR(state, "childBools"); - std::string parent = ATTR(state, "parent"); - - VContainer exitsetters = VOR; - size_t j = 0; - for (auto transIter = _transitions.begin(); transIter != _transitions.end(); transIter++, j++) { - DOMElement* transition = *transIter; - std::string exitSet = ATTR(transition, "exitSetBools"); - if (exitSet[i] == '1') { - *exitsetters += VLINE("in_optimal_transition_set_" + toStr(j) + "_sig "); - } - } - - VBranch* tree = (VASSIGN, - VLINE("in_exit_set_" + toStr(i) + "_sig"), - (VAND, - VLINE("state_active_" + toStr(i) + "_sig"), - exitsetters)); - - tree->print(stream); - stream << ";" << std::endl; - } + stream << "-- exit set selection" << std::endl; + + size_t i = 0; + for (auto stateIter = _states.begin(); stateIter != _states.end(); stateIter++, i++) { + DOMElement* state = *stateIter; + + std::string completion = ATTR(state, "completionBools"); + std::string ancestors = ATTR(state, "ancBools"); + std::string children = ATTR(state, "childBools"); + std::string parent = ATTR(state, "parent"); + + VContainer exitsetters = VOR; + size_t j = 0; + for (auto transIter = _transitions.begin(); transIter != _transitions.end(); transIter++, j++) { + DOMElement* transition = *transIter; + std::string exitSet = ATTR(transition, "exitSetBools"); + if (exitSet[i] == '1') { + *exitsetters += VLINE("in_optimal_transition_set_" + toStr(j) + "_sig "); + } + } + + VBranch* tree = (VASSIGN, + VLINE("in_exit_set_" + toStr(i) + "_sig"), + (VAND, + VLINE("state_active_" + toStr(i) + "_sig"), + exitsetters)); + + tree->print(stream); + stream << ";" << std::endl; + } } void ChartToVHDL::writeEntrySet(std::ostream & stream) { - stream << "-- entry set selection" << std::endl; - - size_t i = 0; - for (auto stateIter = _states.begin(); stateIter != _states.end(); stateIter++, i++) { - DOMElement* state = *stateIter; - - VBranch* tree = (VASSIGN, - VLINE("in_entry_set_" + toStr(i) + "_sig"), - (VAND, - VLINE("in_complete_entry_set_" + toStr(i) + "_sig"), - (VOR, VLINE("in_exit_set_" + toStr(i) + "_sig"), - (VNOT, VLINE("state_active_" + toStr(i) + "_sig"))))); - - tree->print(stream); - stream << ";" << std::endl; - } + stream << "-- entry set selection" << std::endl; + + size_t i = 0; + for (auto stateIter = _states.begin(); stateIter != _states.end(); stateIter++, i++) { + DOMElement* state = *stateIter; + + VBranch* tree = (VASSIGN, + VLINE("in_entry_set_" + toStr(i) + "_sig"), + (VAND, + VLINE("in_complete_entry_set_" + toStr(i) + "_sig"), + (VOR, VLINE("in_exit_set_" + toStr(i) + "_sig"), + (VNOT, VLINE("state_active_" + toStr(i) + "_sig"))))); + + tree->print(stream); + stream << ";" << std::endl; + } } void ChartToVHDL::writeDefaultCompletions(std::ostream & stream) { - // TODO direct connect the line in complete entry set (no extra line needed ...) - stream << "-- default completion assignments" << std::endl; - stream << "-- indikates if the state for which I am the def-completion is active" << std::endl; - std::map > completions; - - size_t i = 0; - for (auto stateIter = _states.begin(); stateIter != _states.end(); stateIter++, i++) { - DOMElement* state = *stateIter; - - completions[state]; // initialize other completions to 0 - - // we just need this if parent is a compound state - std::string parent = ATTR(state, "parent"); - - if (getParentState(state) != NULL - && isCompound(getParentState(state))) { - - // Am I default completen ? - std::string completion = ATTR_CAST(_states[strTo(parent)], "completionBools"); - if (completion[i] == '1') { - // Yes? then give me the parent line - completions[state].push_back(getParentState(state)); - - } - } - } - - auto complIter = completions.begin(); - while (complIter != completions.end()) { - const DOMElement* state(complIter->first); - const std::list refs(complIter->second); - - std::string index = ATTR(state, "documentOrder"); - VContainer defaultCompleters = VOR; - - for (auto ref : refs) { - // *defaultCompleters += VLINE("in_complete_entry_set_" + - // TODO: default completion just when state is entered the first time ? - // if yes then we use the following code. If not we have to revert - *defaultCompleters += VLINE("in_entry_set_" + - ATTR_CAST(ref, "documentOrder") + "_sig "); - } - - VBranch* tree = (VASSIGN, - VLINE("default_completion_" + index + "_sig"), defaultCompleters); - - tree->print(stream); - stream << ";" << std::endl; - - complIter++; - } + // TODO direct connect the line in complete entry set (no extra line needed ...) + stream << "-- default completion assignments" << std::endl; + stream << "-- indikates if the state for which I am the def-completion is active" << std::endl; + std::map > completions; + + size_t i = 0; + for (auto stateIter = _states.begin(); stateIter != _states.end(); stateIter++, i++) { + DOMElement* state = *stateIter; + + completions[state]; // initialize other completions to 0 + + // we just need this if parent is a compound state + std::string parent = ATTR(state, "parent"); + + if (getParentState(state) != NULL + && isCompound(getParentState(state))) { + + // Am I default completen ? + std::string completion = ATTR_CAST(_states[strTo(parent)], "completionBools"); + if (completion[i] == '1') { + // Yes? then give me the parent line + completions[state].push_back(getParentState(state)); + + } + } + } + + auto complIter = completions.begin(); + while (complIter != completions.end()) { + const DOMElement* state(complIter->first); + const std::list refs(complIter->second); + + std::string index = ATTR(state, "documentOrder"); + VContainer defaultCompleters = VOR; + + for (auto ref : refs) { + // *defaultCompleters += VLINE("in_complete_entry_set_" + + // TODO: default completion just when state is entered the first time ? + // if yes then we use the following code. If not we have to revert + *defaultCompleters += VLINE("in_entry_set_" + + ATTR_CAST(ref, "documentOrder") + "_sig "); + } + + VBranch* tree = (VASSIGN, + VLINE("default_completion_" + index + "_sig"), defaultCompleters); + + tree->print(stream); + stream << ";" << std::endl; + + complIter++; + } } void ChartToVHDL::writeCompleteEntrySet(std::ostream & stream) { - stream << "-- complete entry set selection" << std::endl; - - size_t i = 0; - for (auto stateIter = _states.begin(); stateIter != _states.end(); stateIter++, i++) { - DOMElement* state = *stateIter; - - std::string completion = ATTR(state, "completionBools"); - std::string ancestors = ATTR(state, "ancBools"); - std::string children = ATTR(state, "childBools"); - std::string parent = ATTR(state, "parent"); - - VContainer optimalEntrysetters = VOR; - size_t j = 0; - for (auto transIter = _transitions.begin(); transIter != _transitions.end(); transIter++, j++) { - DOMElement* transition = *transIter; - - std::string targetSet = ATTR(transition, "targetBools"); - if (targetSet[i] == '1') {// <- ? TODO Was ist hier der vergleich? - *optimalEntrysetters += VLINE("in_optimal_transition_set_" + toStr(j) + "_sig"); - } - } - - VContainer completeEntrysetters = VOR; - stream << "--" << state->getNodeName() << std::endl; // for debugging - if (isCompound(state) || isParallel(state)) { // <- true for scxml? TODO - for (size_t j = 0; j < _states.size(); j++) { - if (children[j] != '1') // if is child of state j - continue; - *completeEntrysetters += VLINE("in_complete_entry_set_up_" + toStr(j) + "_sig"); - } - } - - VBranch* tree = (VASSIGN, - VLINE("in_complete_entry_set_up_" + toStr(i) + "_sig"), - (VOR, optimalEntrysetters, completeEntrysetters) - ); - tree->print(stream); - stream << ";" << std::endl; + stream << "-- complete entry set selection" << std::endl; + + size_t i = 0; + for (auto stateIter = _states.begin(); stateIter != _states.end(); stateIter++, i++) { + DOMElement* state = *stateIter; + + std::string completion = ATTR(state, "completionBools"); + std::string ancestors = ATTR(state, "ancBools"); + std::string children = ATTR(state, "childBools"); + std::string parent = ATTR(state, "parent"); + + VContainer optimalEntrysetters = VOR; + size_t j = 0; + for (auto transIter = _transitions.begin(); transIter != _transitions.end(); transIter++, j++) { + DOMElement* transition = *transIter; + + std::string targetSet = ATTR(transition, "targetBools"); + if (targetSet[i] == '1') {// <- ? TODO Was ist hier der vergleich? + *optimalEntrysetters += VLINE("in_optimal_transition_set_" + toStr(j) + "_sig"); + } + } + + VContainer completeEntrysetters = VOR; + stream << "--" << state->getNodeName() << std::endl; // for debugging + if (isCompound(state) || isParallel(state)) { // <- true for scxml? TODO + for (size_t j = 0; j < _states.size(); j++) { + if (children[j] != '1') // if is child of state j + continue; + *completeEntrysetters += VLINE("in_complete_entry_set_up_" + toStr(j) + "_sig"); + } + } + + VBranch* tree = (VASSIGN, + VLINE("in_complete_entry_set_up_" + toStr(i) + "_sig"), + (VOR, optimalEntrysetters, completeEntrysetters) + ); + tree->print(stream); + stream << ";" << std::endl; #if 0 - stream << "in_complete_entry_set_up_" << toStr(i) << "_sig <= ('0'" << std::endl; - - for (size_t j = 0; j < _transitions.size(); j++) { - Element transition(_transitions[j]); - // std::cout << transition; - std::string targetSet = ATTR(transition, "targetBools"); - if (targetSet[i] == '1') { - stream << " or in_optimal_transition_set_" << toStr(j) << std::endl; - } - } - if (isCompound(state)) { - for (size_t j = 0; j < _states.size(); j++) { - if (children[j] != '1') - continue; - - stream << " or in_complete_entry_set_up_" << toStr(j) << "_sig" << std::endl; - } - - } - stream << ");" << std::endl; + stream << "in_complete_entry_set_up_" << toStr(i) << "_sig <= ('0'" << std::endl; + + for (size_t j = 0; j < _transitions.size(); j++) { + Element transition(_transitions[j]); + // std::cout << transition; + std::string targetSet = ATTR(transition, "targetBools"); + if (targetSet[i] == '1') { + stream << " or in_optimal_transition_set_" << toStr(j) << std::endl; + } + } + if (isCompound(state)) { + for (size_t j = 0; j < _states.size(); j++) { + if (children[j] != '1') + continue; + + stream << " or in_complete_entry_set_up_" << toStr(j) << "_sig" << std::endl; + } + + } + stream << ");" << std::endl; #endif - } - - for (auto state : _states) { - std::string completion = ATTR(state, "completionBools"); - std::string ancestors = ATTR(state, "ancBools"); - std::string parent = ATTR(state, "parent"); - - if (parent.size() == 0) { - continue; // TODO: FixMe <-- ? - } - - VContainer tmp1 = VAND; - // if parent is compound - if (getParentState(state) != NULL && - isCompound(getParentState(state))) { - std::string children = ATTR_CAST(_states[strTo(parent)], - "childBools"); - // TODO: do not add default_completion line if not needed - // --> just if this state is the default completion of parent - // --> init attr. or if not present first in document order <-- = completion bool ? - *tmp1 += VLINE("default_completion_" + ATTR(state, "documentOrder") + "_sig"); - - //TODO check this - for (size_t j = 0; j < _states.size(); j++) { - if (children[j] != '1') - continue; - *tmp1 += (VAND, - (VNOT, - (VAND, - VLINE("state_active_" + toStr(j) + "_sig"), - (VNOT, - VLINE("in_exit_set_" + toStr(j) + "_sig"))))); - - } - - } - - // if parent is parallel - if (getParentState(state) != NULL && - isParallel(getParentState(state))) { - *tmp1 += VLINE("in_complete_entry_set_" + toStr(parent) + "_sig"); - } - - VBranch* tree = (VASSIGN, - VLINE("in_complete_entry_set_" + toStr(i) + "_sig"), - (VOR, - VLINE("in_complete_entry_set_up_" + ATTR(state, "documentOrder") + "_sig"), - tmp1)); - - tree->print(stream); - stream << ";" << std::endl; + } + + for (auto state : _states) { + std::string completion = ATTR(state, "completionBools"); + std::string ancestors = ATTR(state, "ancBools"); + std::string parent = ATTR(state, "parent"); + + if (parent.size() == 0) { + continue; // TODO: FixMe <-- ? + } + + VContainer tmp1 = VAND; + // if parent is compound + if (getParentState(state) != NULL && + isCompound(getParentState(state))) { + std::string children = ATTR_CAST(_states[strTo(parent)], + "childBools"); + // TODO: do not add default_completion line if not needed + // --> just if this state is the default completion of parent + // --> init attr. or if not present first in document order <-- = completion bool ? + *tmp1 += VLINE("default_completion_" + ATTR(state, "documentOrder") + "_sig"); + + //TODO check this + for (size_t j = 0; j < _states.size(); j++) { + if (children[j] != '1') + continue; + *tmp1 += (VAND, + (VNOT, + (VAND, + VLINE("state_active_" + toStr(j) + "_sig"), + (VNOT, + VLINE("in_exit_set_" + toStr(j) + "_sig"))))); + + } + + } + + // if parent is parallel + if (getParentState(state) != NULL && + isParallel(getParentState(state))) { + *tmp1 += VLINE("in_complete_entry_set_" + toStr(parent) + "_sig"); + } + + VBranch* tree = (VASSIGN, + VLINE("in_complete_entry_set_" + toStr(i) + "_sig"), + (VOR, + VLINE("in_complete_entry_set_up_" + ATTR(state, "documentOrder") + "_sig"), + tmp1)); + + tree->print(stream); + stream << ";" << std::endl; #if 0 - stream << "in_complete_entry_set_" << toStr(i) << "_sig <= (in_complete_entry_set_up_" << toStr(i) << "_sig or (" << std::endl; + stream << "in_complete_entry_set_" << toStr(i) << "_sig <= (in_complete_entry_set_up_" << toStr(i) << "_sig or (" << std::endl; - if (isParallel(Element(_states[strTo(parent)]))) { - stream << " in_complete_entry_set_" << toStr(parent) << "_sig" << std::endl; - } else if (isCompound(Element(_states[strTo(parent)]))) { - stream << " default_completion_" << toStr(parent) << "_sig" << std::endl; + if (isParallel(Element(_states[strTo(parent)]))) { + stream << " in_complete_entry_set_" << toStr(parent) << "_sig" << std::endl; + } else if (isCompound(Element(_states[strTo(parent)]))) { + stream << " default_completion_" << toStr(parent) << "_sig" << std::endl; - for (size_t j = 0; j < _states.size(); j++) { - if (children[j] != '1') - continue; - stream << " and not (is_active" << toStr(j) << "_sig and not in_exit_set_" << toStr(j) << "_sig)" << std::endl; + for (size_t j = 0; j < _states.size(); j++) { + if (children[j] != '1') + continue; + stream << " and not (is_active" << toStr(j) << "_sig and not in_exit_set_" << toStr(j) << "_sig)" << std::endl; - } - } + } + } - stream << ");" << std::endl; + stream << ");" << std::endl; #endif - } + } } void ChartToVHDL::writeStateHandler(std::ostream & stream) { - // updater for current state - stream << "-- State Handler" << std::endl; - stream << "-- updates current state" << std::endl; - stream << "state_proc: process(clk, rst, stall)" << std::endl; - stream << "begin" << std::endl; - stream << " if rst = '1' then" << std::endl; - - size_t i = 0; - for (auto stateIter = _states.begin(); stateIter != _states.end(); stateIter++, i++) { + // updater for current state + stream << "-- State Handler" << std::endl; + stream << "-- updates current state" << std::endl; + stream << "state_proc: process(clk, rst, stall)" << std::endl; + stream << "begin" << std::endl; + stream << " if rst = '1' then" << std::endl; + + size_t i = 0; + for (auto stateIter = _states.begin(); stateIter != _states.end(); stateIter++, i++) { // DOMElement* state = *stateIter; - stream << " state_active_" << toStr(i) << "_sig <= " << "'0';" << std::endl; - } - - stream << " in_complete_entry_set_0_sig <= '1';" << std::endl; - stream << " elsif (rising_edge(clk) and stall = '0') then" << std::endl; - stream << " in_complete_entry_set_0_sig <= '0';" << std::endl; - - i = 0; - for (auto stateIter = _states.begin(); stateIter != _states.end(); stateIter++, i++) { - // DOMElement* state = *stateIter; - stream << " state_active_" << toStr(i) << "_sig <= " << "state_next_" << toStr(i) << "_sig;" << std::endl; - } - - stream << " end if;" << std::endl; - stream << "end process;" << std::endl; - stream << std::endl; + stream << " state_active_" << toStr(i) << "_sig <= " << "'0';" << std::endl; + } + + stream << " in_complete_entry_set_0_sig <= '1';" << std::endl; + stream << " elsif (rising_edge(clk) and stall = '0') then" << std::endl; + stream << " in_complete_entry_set_0_sig <= '0';" << std::endl; + + i = 0; + for (auto stateIter = _states.begin(); stateIter != _states.end(); stateIter++, i++) { + // DOMElement* state = *stateIter; + stream << " state_active_" << toStr(i) << "_sig <= " << "state_next_" << toStr(i) << "_sig;" << std::endl; + } + + stream << " end if;" << std::endl; + stream << "end process;" << std::endl; + stream << std::endl; } void ChartToVHDL::writeSystemSignalMapping(std::ostream & stream) { - stream << "-- system signals" << std::endl; - std::list topLevelFinal = DOMUtils::filterChildElements(XML_PREFIX(_scxml).str() + "final", _scxml); - - VContainer tlf = VOR; - for (auto final : topLevelFinal) { - *tlf += VLINE("state_active_" + ATTR(final, "documentOrder") + "_sig"); - - } - - VBranch* tree = (VASSIGN, - VLINE("completed_sig"), - tlf); - - tree->print(stream); - stream << ";" << std::endl; - - // tmp mapping for events - stream << "stall <= not en or completed_sig or ( int_event_empty and not spontaneous_en ) ; " << std::endl; - stream << std::endl; - - // interface signals - stream << "-- interface signals" << std::endl; - for (auto state : _states) { - stream << "state_active_" << ATTR(state, "documentOrder") - << "_o <= state_active_" << ATTR(state, "documentOrder") - << "_sig;" << std::endl; - if (DOMUtils::filterChildElements(XML_PREFIX(_scxml).str() + "onexit", state).size() > 0) { - stream << "exit_set_" << ATTR(state, "documentOrder") - << "_o <= in_exit_set_" << ATTR(state, "documentOrder") - << "_sig;" << std::endl; - } - - if (DOMUtils::filterChildElements(XML_PREFIX(_scxml).str() + "onentry", state).size() > 0) { - stream << "entry_set_" << ATTR(state, "documentOrder") - << "_o <= in_entry_set_" << ATTR(state, "documentOrder") - << "_sig;" << std::endl; - } - } - - for (auto transition : _transitions) { - if (DOMUtils::filterChildType(DOMNode::ELEMENT_NODE, transition).size() > 0) { - stream << "transition_set_" << ATTR(transition, "postFixOrder") - << "_o <= in_optimal_transition_set_" << ATTR(transition, "postFixOrder") - << "_sig;" << std::endl; - } - } - - stream << "completed_o <= completed_sig; " << std::endl; - stream << "error_o <= reg_error_out; " << std::endl; - stream << std::endl; + stream << "-- system signals" << std::endl; + std::list topLevelFinal = DOMUtils::filterChildElements(XML_PREFIX(_scxml).str() + "final", _scxml); + + VContainer tlf = VOR; + for (auto final : topLevelFinal) { + *tlf += VLINE("state_active_" + ATTR(final, "documentOrder") + "_sig"); + + } + + VBranch* tree = (VASSIGN, + VLINE("completed_sig"), + tlf); + + tree->print(stream); + stream << ";" << std::endl; + + // tmp mapping for events + stream << "stall <= not en or completed_sig or ( int_event_empty and not spontaneous_en ) ; " << std::endl; + stream << std::endl; + + // interface signals + stream << "-- interface signals" << std::endl; + for (auto state : _states) { + stream << "state_active_" << ATTR(state, "documentOrder") + << "_o <= state_active_" << ATTR(state, "documentOrder") + << "_sig;" << std::endl; + if (DOMUtils::filterChildElements(XML_PREFIX(_scxml).str() + "onexit", state).size() > 0) { + stream << "exit_set_" << ATTR(state, "documentOrder") + << "_o <= in_exit_set_" << ATTR(state, "documentOrder") + << "_sig;" << std::endl; + } + + if (DOMUtils::filterChildElements(XML_PREFIX(_scxml).str() + "onentry", state).size() > 0) { + stream << "entry_set_" << ATTR(state, "documentOrder") + << "_o <= in_entry_set_" << ATTR(state, "documentOrder") + << "_sig;" << std::endl; + } + } + + for (auto transition : _transitions) { + if (DOMUtils::filterChildType(DOMNode::ELEMENT_NODE, transition).size() > 0) { + stream << "transition_set_" << ATTR(transition, "postFixOrder") + << "_o <= in_optimal_transition_set_" << ATTR(transition, "postFixOrder") + << "_sig;" << std::endl; + } + } + + stream << "completed_o <= completed_sig; " << std::endl; + stream << "error_o <= reg_error_out; " << std::endl; + stream << std::endl; } } \ No newline at end of file diff --git a/src/uscxml/transform/ChartToVHDL.h b/src/uscxml/transform/ChartToVHDL.h index 85fd30d..0a58b4e 100644 --- a/src/uscxml/transform/ChartToVHDL.h +++ b/src/uscxml/transform/ChartToVHDL.h @@ -161,19 +161,19 @@ protected: void writeTypes(std::ostream& stream); void writeIncludes(std::ostream& stream); - - // top layer components + + // top layer components void writeFiFo(std::ostream& stream); void writeEventController(std::ostream & stream); void writeMicroStepper(std::ostream& stream); void writeTestbench(std::ostream & stream); - - // system + + // system void writeSignalsAndComponents(std::ostream& stream); void writeSystemSignalMapping(std::ostream& stream); void writeModuleInstantiation(std::ostream& stream); - // combinatorial logic + // combinatorial logic void writeOptimalTransitionSetSelection(std::ostream& stream); void writeExitSet(std::ostream & stream); void writeEntrySet(std::ostream & stream); @@ -182,24 +182,24 @@ protected: void writeCompleteEntrySet(std::ostream & stream); void writeActiveStateNplusOne(std::ostream & stream); - // handler + // handler void writeStateHandler(std::ostream& stream); void writeResetHandler(std::ostream & stream); void writeSpontaneousHandler(std::ostream & stream); void writeInternalEventHandler(std::ostream & stream); void writeErrorHandler(std::ostream& stream); - - // event generation - void writeExContentBlock(std::ostream & stream, std::string index, - std::list< XERCESC_NS::DOMElement* > commandSequence); - + + // event generation + void writeExContentBlock(std::ostream & stream, std::string index, + std::list< XERCESC_NS::DOMElement* > commandSequence); + Trie _eventTrie; - std::list< XERCESC_NS::DOMElement* > _execContent; + std::list< XERCESC_NS::DOMElement* > _execContent; private: std::string eventNameEscape(const std::string& eventName); - std::string getLineForExecContent(const XERCESC_NS::DOMNode* elem); + std::string getLineForExecContent(const XERCESC_NS::DOMNode* elem); }; diff --git a/src/uscxml/transform/promela/PromelaCodeAnalyzer.cpp b/src/uscxml/transform/promela/PromelaCodeAnalyzer.cpp new file mode 100644 index 0000000..4d1d8d5 --- /dev/null +++ b/src/uscxml/transform/promela/PromelaCodeAnalyzer.cpp @@ -0,0 +1,596 @@ +/** + * @file + * @author 2016 Stefan Radomski (stefan.radomski@cs.tu-darmstadt.de) + * @copyright Simplified BSD + * + * @cond + * This program is free software: you can redistribute it and/or modify + * it under the terms of the FreeBSD license as published by the FreeBSD + * project. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * You should have received a copy of the FreeBSD license along with this + * program. If not, see . + * @endcond + */ + +#define MAX_MACRO_CHARS 64 + +#include "PromelaCodeAnalyzer.h" +#include "uscxml/transform/ChartToPromela.h" +#include "uscxml/util/Predicates.h" +#include "uscxml/util/DOM.h" +#include "uscxml/util/String.h" + +#include + +namespace uscxml { + +using namespace XERCESC_NS; + +void PromelaCodeAnalyzer::analyze(ChartToPromela* interpreter) { + + /** + Create macro names for state identifiers + Do not add as literals as they are not unique with nested state-charts + */ + { + for (size_t i = 0; i < interpreter->_states.size(); i++) { + DOMElement* state = interpreter->_states[i]; + if (HAS_ATTR(state, "id")) { + createMacroName(ATTR(state, "id")); + } + } + } +// _lastStrIndex = interpreter->_states.size(); + + /** Find all event names that might occur */ + { + std::list internalEventNames = DOMUtils::inDocumentOrder({ + XML_PREFIX(interpreter->_scxml).str() + "transition", + XML_PREFIX(interpreter->_scxml).str() + "raise", + XML_PREFIX(interpreter->_scxml).str() + "send" + }, interpreter->_scxml); + + for (auto internalEventName : internalEventNames) { + if (HAS_ATTR_CAST(internalEventName, "event")) { + std::string eventNames = ATTR_CAST(internalEventName, "event"); + std::list events = tokenize(eventNames); + for (std::list::iterator eventIter = events.begin(); + eventIter != events.end(); eventIter++) { + std::string eventName = *eventIter; + if (boost::ends_with(eventName, "*")) + eventName = eventName.substr(0, eventName.size() - 1); + if (boost::ends_with(eventName, ".")) + eventName = eventName.substr(0, eventName.size() - 1); + if (eventName.size() > 0) + _eventTrie.addWord(eventName); + } + } + } + + for (auto state : interpreter->_states) { + if (HAS_ATTR(state, "id") && (isCompound(state) || isParallel(state))) { + _eventTrie.addWord("done.state." + ATTR(state, "id")); + } + } + } + + // add event names from trie to string literals + std::list events = _eventTrie.getWordsWithPrefix(""); + for (auto event : events) { + addLiteral(event->value); + } + + + /** Find all string literals */ + { + // string literals for raise / send content + std::list contents = DOMUtils::inDocumentOrder({ + XML_PREFIX(interpreter->_scxml).str() + "content" + }, interpreter->_scxml); + + for (auto content : contents) { + std::string contentStr = spaceNormalize(X(((DOMElement*)content)->getFirstChild()->getNodeValue())); + if (!isNumeric(contentStr.c_str(), 10)) { + addLiteral(contentStr); + } + } + } + + /* add platform variables as string literals */ + addLiteral(interpreter->_prefix + "_sessionid"); + addLiteral(interpreter->_prefix + "_name"); + + + /** Extract and analyze source code */ + { + std::list withCond = DOMUtils::inDocumentOrder({ + XML_PREFIX(interpreter->_scxml).str() + "transition", + XML_PREFIX(interpreter->_scxml).str() + "if", + XML_PREFIX(interpreter->_scxml).str() + "elseif" + }, interpreter->_scxml); + + for (auto cond : withCond) { + if (HAS_ATTR(cond, "cond")) { + std::string code = ATTR_CAST(cond, "cond"); + code = sanitizeCode(code); + addCode(code, interpreter); + cond->setAttribute(X("cond"), X(code)); + } + } + + std::list withExpr = DOMUtils::inDocumentOrder({ + XML_PREFIX(interpreter->_scxml).str() + "log", + XML_PREFIX(interpreter->_scxml).str() + "data", + XML_PREFIX(interpreter->_scxml).str() + "assign", + XML_PREFIX(interpreter->_scxml).str() + "content", + XML_PREFIX(interpreter->_scxml).str() + "param" + }, interpreter->_scxml); + + for (auto expr : withExpr) { + if (HAS_ATTR(expr, "expr")) { + std::string code = ATTR_CAST(expr, "expr"); + code = sanitizeCode(code); + addCode(code, interpreter); + expr->setAttribute(X("expr"), X(code)); + } + } + + std::list withLocation = DOMUtils::inDocumentOrder({ + XML_PREFIX(interpreter->_scxml).str() + "assign" + }, interpreter->_scxml); + + for (auto location : withLocation) { + if (HAS_ATTR(location, "location")) { + std::string code = ATTR_CAST(location, "location"); + code = sanitizeCode(code); + addCode(code, interpreter); + location->setAttribute(X("location"), X(code)); + } + } + + std::list withText = DOMUtils::inDocumentOrder({ + XML_PREFIX(interpreter->_scxml).str() + "script" + }, interpreter->_scxml); + + for (auto text : withText) { + std::list texts = DOMUtils::filterChildType(DOMNode::TEXT_NODE, text, true); + for (auto textBlock : texts) { + DOMText* textText = static_cast(textBlock); + std::string code = X(textText->getNodeValue()).str(); + if (code.size() > 0) { + code = sanitizeCode(code); + addCode(code, interpreter); + textText->setNodeValue(X(code)); + } + } + } + + std::list foreachs = DOMUtils::inDocumentOrder({ + XML_PREFIX(interpreter->_scxml).str() + "foreach" + }, interpreter->_scxml); + + for (auto foreach : foreachs) { + if (HAS_ATTR(foreach, "index")) { + addCode(ATTR(foreach, "index"), interpreter); + } else { + _hasIndexLessLoops = true; + } + if (HAS_ATTR(foreach, "item")) { + addCode(ATTR(foreach, "item"), interpreter); + } + } + + // do we need sendid / invokeid? + { + std::list invokes = DOMUtils::inDocumentOrder({XML_PREFIX(interpreter->_scxml).str() + "invoke"}, interpreter->_scxml); + std::list sends = DOMUtils::inDocumentOrder({XML_PREFIX(interpreter->_scxml).str() + "send"}, interpreter->_scxml); + std::list cancels = DOMUtils::inDocumentOrder({XML_PREFIX(interpreter->_scxml).str() + "cancel"}, interpreter->_scxml); + + if (cancels.size() > 0) { + addCode("_event.invokeid", interpreter); + _usesCancel = true; + } + + for (auto send : sends) { + if (HAS_ATTR(send, "idlocation")) { + addCode("_event.sendid", interpreter); + } + if (HAS_ATTR(send, "id")) { + addLiteral(ATTR(send, "id")); + addCode("_event.sendid", interpreter); + } + + // do we need delays? + if (HAS_ATTR(send, "delay") || HAS_ATTR(send, "delayexpr")) { + addCode("_event.delay", interpreter); +#if NEW_DELAY_RESHUFFLE +#else + addCode("_event.seqNr", interpreter); +#endif + } + } + } + + // add all namelist entries to the _event structure + { + std::list withNamelists; + withNamelists.splice(withNamelists.end(), DOMUtils::inDocumentOrder({XML_PREFIX(interpreter->_scxml).str() + "send"}, interpreter->_scxml)); + withNamelists.splice(withNamelists.end(), DOMUtils::inDocumentOrder({XML_PREFIX(interpreter->_scxml).str() + "invoke"}, interpreter->_scxml)); + for (auto withNamelist : withNamelists) { + if (HAS_ATTR(withNamelist, "namelist")) { + std::string namelist = ATTR(withNamelist, "namelist"); + std::list names = tokenize(namelist); + for (std::list::iterator nameIter = names.begin(); nameIter != names.end(); nameIter++) { + addCode("_event.data." + *nameIter + " = 0;", interpreter); // introduce for _event_t typedef + } + } + } + } + + } + +} + +std::string PromelaCodeAnalyzer::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 PromelaCodeAnalyzer::addCode(const std::string& code, ChartToPromela* interpreter) { + PromelaParser parser(code); + // parser.dump(); + + // find all strings + std::list astNodes; + astNodes.push_back(parser.ast); + + while(astNodes.size() > 0) { + PromelaParserNode* node = astNodes.front(); + astNodes.pop_front(); + + // node->dump(); + + bool hasValue = false; + int assignedValue = 0; + + + 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_ASGN: + if (node->operands.back()->type == PML_CONST) { + hasValue = true; + if (isInteger(node->operands.back()->value.c_str(), 10)) { + assignedValue = strTo(node->operands.back()->value); + } + } + if (node->operands.back()->type == PML_STRING) { + // remember strings for later + astNodes.push_back(node->operands.back()); + } + if (node->operands.front()->type == PML_CMPND) { + node = node->operands.front(); + } else { + break; + } + // if (node->operands.front()->type != PML_NAME) + // break; // this will skip array assignments + case PML_CMPND: { + std::string nameOfType; + std::list::iterator opIter = node->operands.begin(); + if ((*opIter)->type != PML_NAME) { + node->dump(); + return; + assert(false); + } + + PromelaTypedef* td = &_typeDefs; + std::string seperator; + + while(opIter != node->operands.end()) { + switch ((*opIter)->type) { + case PML_NAME: + td = &td->types[(*opIter)->value]; + td->occurrences.insert(interpreter); + + 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]; + td->occurrences.insert(interpreter); + + nameOfType += seperator + name->value; + td->name = nameOfType + "_t"; + + if (isInteger(subscript->value.c_str(), 10)) { + td->arraySize = strTo(subscript->value); + } + break; + } + default: + if ((*opIter)->type == PML_CONST) { + // break fall through from ASGN + break; + } + // 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++; + } + + if (hasValue) { + if (td->maxValue < assignedValue) + td->maxValue = assignedValue; + if (td->minValue > assignedValue) + td->minValue = assignedValue; + } + + continue; // skip processing nested AST nodes + } + case PML_NAME: { + _typeDefs.types[node->value].occurrences.insert(interpreter); + _typeDefs.types[node->value].minValue = 0; + _typeDefs.types[node->value].maxValue = 0; + // test325 + if (node->value.compare("_ioprocessors") == 0) { + addCode("_ioprocessors.scxml.location", interpreter); + } + + break; + } + + default: + // node->dump(); + break; + // assert(false); + } + + astNodes.insert(astNodes.end(), node->operands.begin(), node->operands.end()); + + } +} + +void PromelaCodeAnalyzer::addLiteral(const std::string& literal, int forceIndex) { + if (boost::starts_with(literal, "'")) + throw std::runtime_error("Literal " + literal + " passed with quotes"); + + if (_literals.find(literal) != _literals.end()) + return; + _literals.insert(literal); + createMacroName(literal); + enumerateLiteral(literal, forceIndex); +} + +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::macroForLiteral(const std::string& literal) { + if (boost::starts_with(literal, "'")) + throw std::runtime_error("Literal " + literal + " passed with quotes"); + + if (_strMacros.find(literal) == _strMacros.end()) + throw std::runtime_error("No macro for literal '" + literal + "' known"); + return _strMacros[literal]; +} + + +std::string PromelaCodeAnalyzer::createMacroName(const std::string& literal) { + if (_strMacros.find(literal) != _strMacros.end()) + return _strMacros[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; + if(macroName.length() < 1) + macroName = "_EMPTY_STRING"; + if(macroName.length() < 2 && macroName[0] == '_') + macroName = "_WEIRD_CHARS"; + + 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); + _strMacros[literal] = macroName; + return macroName; +} + +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::adaptCode(const std::string& code, const std::string& prefix) { + // for (std::map::const_iterator litIter = _strMacros.begin(); litIter != _strMacros.end(); litIter++) { + // boost::replace_all(replaced, "'" + litIter->first + "'", litIter->second); + // } + // boost::replace_all(replaced, "_event", prefix + "_event"); + // replace all variables from analyzer + + std::string processed = code; + std::stringstream processedStr; + std::list > posList; + std::list >::iterator posIter; + size_t lastPos; + + // prepend all identifiers with our prefix + { + PromelaParser parsed(processed); + // parsed.dump(); + posList = getTokenPositions(code, PML_NAME, parsed.ast); + posList.sort(); + posIter = posList.begin(); + lastPos = 0; + + while (posIter != posList.end()) { + std::string token = code.substr(posIter->first, posIter->second - posIter->first); + if (std::all_of(token.begin(), token.end(), ::isupper) && false) { + // assume it is a state-name macro + processedStr << code.substr(lastPos, posIter->first - lastPos) << token; + } else { + processedStr << code.substr(lastPos, posIter->first - lastPos) << prefix << token; + } + lastPos = posIter->second; + posIter++; + } + processedStr << processed.substr(lastPos, processed.size() - lastPos); + + processed = processedStr.str(); + processedStr.clear(); + processedStr.str(""); + } + + // replace string literals + { + PromelaParser parsed(processed); + posList = getTokenPositions(code, PML_STRING, parsed.ast); + posList.sort(); + posIter = posList.begin(); + lastPos = 0; + + while (posIter != posList.end()) { + processedStr << processed.substr(lastPos, posIter->first - lastPos); + // std::cout << processed.substr(posIter->first + 1, posIter->second - posIter->first - 2) << std::endl; + assert(_strMacros.find(processed.substr(posIter->first + 1, posIter->second - posIter->first - 2)) != _strMacros.end()); + processedStr << _strMacros[processed.substr(posIter->first + 1, posIter->second - posIter->first - 2)]; + lastPos = posIter->second; + posIter++; + } + processedStr << processed.substr(lastPos, processed.size() - lastPos); + + processed = processedStr.str(); + processedStr.clear(); + processedStr.str(""); + } + + return processed; +} + +std::list > PromelaCodeAnalyzer::getTokenPositions(const std::string& expr, int type, PromelaParserNode* ast) { + std::list > posList; + if (ast->type == type && ast->loc != NULL) { + // ast->dump(); + if (type == PML_NAME && ast->parent && + ((ast->parent->type == PML_CMPND && ast->parent->operands.front() != ast) || + (ast->parent->parent && ast->parent->type == PML_VAR_ARRAY && ast->parent->parent->type == PML_CMPND))) { + // field in a compound + } else { + if (ast->loc->firstLine == 0) { + posList.push_back(std::make_pair(ast->loc->firstCol, ast->loc->lastCol)); + } else { + int line = ast->loc->firstLine; + size_t lastPos = 0; + while(line > 0) { + lastPos = expr.find_first_of('\n', lastPos + 1); + line--; + } + posList.push_back(std::make_pair(lastPos + ast->loc->firstCol, lastPos + ast->loc->lastCol)); + } + } + } + for (std::list::iterator opIter = ast->operands.begin(); opIter != ast->operands.end(); opIter++) { + std::list > tmp = getTokenPositions(expr, type, *opIter); + posList.insert(posList.end(), tmp.begin(), tmp.end()); + } + return posList; +} + +std::string PromelaCodeAnalyzer::getTypeReset(const std::string& var, const PromelaTypedef& type, const std::string padding) { + std::stringstream assignment; + + std::map::const_iterator typeIter = type.types.begin(); + while(typeIter != type.types.end()) { + const PromelaTypedef& innerType = typeIter->second; + if (innerType.arraySize > 0) { + for (size_t i = 0; i < innerType.arraySize; i++) { + assignment << padding << var << "." << typeIter->first << "[" << i << "] = 0;" << std::endl; + } + } else if (innerType.types.size() > 0) { + assignment << getTypeReset(var + "." + typeIter->first, typeIter->second, padding); + } else { + assignment << padding << var << "." << typeIter->first << " = 0;" << std::endl; + } + typeIter++; + } + return assignment.str(); + +} + +} diff --git a/src/uscxml/transform/promela/PromelaCodeAnalyzer.h b/src/uscxml/transform/promela/PromelaCodeAnalyzer.h new file mode 100644 index 0000000..656b24e --- /dev/null +++ b/src/uscxml/transform/promela/PromelaCodeAnalyzer.h @@ -0,0 +1,150 @@ +/** + * @file + * @author 2016 Stefan Radomski (stefan.radomski@cs.tu-darmstadt.de) + * @copyright Simplified BSD + * + * @cond + * This program is free software: you can redistribute it and/or modify + * it under the terms of the FreeBSD license as published by the FreeBSD + * project. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * You should have received a copy of the FreeBSD license along with this + * program. If not, see . + * @endcond + */ + +#ifndef PROMELACODEANALYZER_H_E89FF519 +#define PROMELACODEANALYZER_H_E89FF519 + +#include "uscxml/transform/Trie.h" +#include "uscxml/plugins/datamodel/promela/PromelaParser.h" +#include "uscxml/plugins/datamodel/promela/parser/promela.tab.hpp" + +#include + +namespace uscxml { + +class ChartToPromela; + +class USCXML_API PromelaCodeAnalyzer { +public: + class PromelaTypedef { + public: + PromelaTypedef() {} + std::string name; + std::string type; + size_t arraySize = 0; + size_t minValue = 0; + size_t maxValue = 0; + std::map types; + std::set occurrences; + + bool operator==(const PromelaTypedef& other) const { + return name == other.name; + } + + }; + + PromelaCodeAnalyzer() : _eventTrie(".") {} + + void analyze(ChartToPromela* interpreter); + + void addCode(const std::string& code, ChartToPromela* interpreter); + void addLiteral(const std::string& stateName, int forceIndex = -1); + + bool usesComplexEventStruct() { + return _typeDefs.types.find("_event") != _typeDefs.types.end() && _typeDefs.types["_event"].types.size() > 0; + } + bool usesEventField(const std::string& fieldName) { + if (usesComplexEventStruct() && _typeDefs.types["_event"].types.find(fieldName) != _typeDefs.types["_event"].types.end()) + return true; + return false; + } + bool usesCancel(const std::string& elementName) { + return _usesCancel; + } + + bool usesEventDataField(const std::string& fieldName) { + if (usesComplexEventStruct() && + _typeDefs.types["_event"].types.find("data") != _typeDefs.types["_event"].types.end() && + _typeDefs.types["_event"].types["data"].types.find(fieldName) != _typeDefs.types["_event"].types["data"].types.end()) + return true; + return false; + } + + std::string getTypeAssignment(const std::string& varTo, const std::string& varFrom, const PromelaTypedef& type, const std::string padding = ""); + std::string getTypeReset(const std::string& var, const PromelaTypedef& type, const std::string padding = ""); + + bool usesInPredicate() { + return _usesInPredicate; + } + void usesInPredicate(bool value) { + _usesInPredicate = value; + } + bool usesPlatformVars() { + return _usesPlatformVars; + } + + bool hasIndexLessLoops() { + return _hasIndexLessLoops; + } + + std::string macroForLiteral(const std::string& literal); + int indexForLiteral(const std::string& literal); + + std::set getLiterals() { + return _literals; + } + std::set getEventsWithPrefix(const std::string& prefix); + + Trie& getTrie() { + return _eventTrie; + } + + std::string adaptCode(const std::string& code, const std::string& prefix); + + static std::string prefixIdentifiers(const std::string& expr, const std::string& prefix); + static std::list > getTokenPositions(const std::string& expr, int type, PromelaParserNode* ast); + + PromelaTypedef& getTypes() { + return _typeDefs; + } + + PromelaTypedef& getType(const std::string& typeName) { + return _typeDefs.types.at(typeName); + } + + std::string sanitizeCode(const std::string& code); + +protected: + void addEvent(const std::string& eventName); + void addState(const std::string& stateName, size_t index); + + std::string createMacroName(const std::string& literal); + int enumerateLiteral(const std::string& literal, int forceIndex = -1); + + std::map _strMacros; // macronames for string literals + std::map _strIndex; // integer enumeration for string + std::set _literals; + + PromelaTypedef _typeDefs; + Trie _eventTrie; + +private: + std::set _macroNameSet; // helper set for uniqueness of macros + int _lastStrIndex = 1; + bool _usesCancel = false; + bool _usesInPredicate = false; + bool _usesPlatformVars = false; + bool _hasIndexLessLoops = false; +}; + + + +} + +#endif /* end of include guard: PROMELACODEANALYZER_H_E89FF519 */ diff --git a/src/uscxml/transform/promela/PromelaInlines.cpp b/src/uscxml/transform/promela/PromelaInlines.cpp new file mode 100644 index 0000000..7d62762 --- /dev/null +++ b/src/uscxml/transform/promela/PromelaInlines.cpp @@ -0,0 +1,165 @@ +/** + * @file + * @author 2016 Stefan Radomski (stefan.radomski@cs.tu-darmstadt.de) + * @copyright Simplified BSD + * + * @cond + * This program is free software: you can redistribute it and/or modify + * it under the terms of the FreeBSD license as published by the FreeBSD + * project. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * You should have received a copy of the FreeBSD license along with this + * program. If not, see . + * @endcond + */ + +#include "PromelaInlines.h" +#include + +namespace uscxml { + +using namespace XERCESC_NS; + +void PromelaInline::dump() { +} + +PromelaInline::PromelaInline(const XERCESC_NS::DOMNode* node) { + if (node->getNodeType() != DOMNode::COMMENT_NODE && node->getNodeType() != DOMNode::TEXT_NODE) + return; // nothing to do + + std::stringstream ssLine(X(node->getNodeValue()).str()); + std::string line; + + while(std::getline(ssLine, line)) { + // skip to first promela line + boost::trim(line); + if (boost::starts_with(line, "promela")) + break; + } + + if (!boost::starts_with(line, "promela")) + return; + + if (false) { + } else if (boost::starts_with(line, "promela-code")) { + type = PROMELA_CODE; + } else if (boost::starts_with(line, "promela-ltl")) { + type = PROMELA_LTL; + } else if (boost::starts_with(line, "promela-event-all")) { + type = PROMELA_EVENT_ALL_BUT; + } else if (boost::starts_with(line, "promela-event")) { + type = PROMELA_EVENT_ONLY; + } else if (boost::starts_with(line, "promela-progress")) { + type = PROMELA_PROGRESS_LABEL; + } else if (boost::starts_with(line, "promela-accept")) { + type = PROMELA_ACCEPT_LABEL; + } else if (boost::starts_with(line, "promela-end")) { + type = PROMELA_END_LABEL; + } + + std::stringstream contentSS; + size_t endType = line.find_first_of(": \n"); + + std::string seperator; + if (endType != std::string::npos && endType + 1 < line.size()) { + contentSS << line.substr(endType + 1, line.size() - endType + 1); + seperator = "\n"; + } + + while(std::getline(ssLine, line)) { + boost::trim(line); + if (boost::starts_with(line, "promela")) { + std::cerr << "Split multiple #promela pragmas into multiple comments!" << std::endl; + break; + } + contentSS << seperator << line; + seperator = "\n"; + } + content = contentSS.str(); + +} + +PromelaInlines::PromelaInlines(const XERCESC_NS::DOMNode* node) { + + std::list levelNodes; + levelNodes.push_back(const_cast(node)); + + size_t level = 0; + while(levelNodes.size() > 0) { + PromelaInline* predecessor = NULL; + + // iterate all nodes at given level + for (auto levelNode : levelNodes) { + + // get all comments + std::list comments = DOMUtils::filterChildType(DOMNode::COMMENT_NODE, levelNode); + for (auto comment : comments) { + + PromelaInline* tmp = new PromelaInline(comment); + if (tmp->type == PromelaInline::PROMELA_NIL) { + delete tmp; + continue; + } + + if (predecessor != NULL) { + tmp->prevSibling = predecessor; + predecessor->nextSibling = tmp; + } + tmp->level = level; + tmp->container = static_cast(levelNode); + predecessor = tmp; + inlines[levelNode].push_back(tmp); + allInlines.push_back(tmp); + } + } + + levelNodes = DOMUtils::filterChildType(DOMNode::ELEMENT_NODE, levelNodes); + level++; + } + +} + +PromelaInlines::~PromelaInlines() { +} + +std::list PromelaInlines::getRelatedTo(const XERCESC_NS::DOMNode* node, + PromelaInline::PromelaInlineType type) { + std::list related; + + auto inlIter = inlines.begin(); + while (inlIter != inlines.end()) { + std::list::iterator pmlIter = inlIter->second.begin(); + while (pmlIter != inlIter->second.end()) { + if ((type != PromelaInline::PROMELA_NIL || (*pmlIter)->type == type) && (*pmlIter)->relatesTo(node)) { + related.push_back(*pmlIter); + } + pmlIter++; + } + inlIter++; + } + return related; +} + +std::list PromelaInlines::getAllOfType(uint32_t type) { + std::list related; + + auto inlIter = inlines.begin(); + while (inlIter != inlines.end()) { + std::list::iterator pmlIter = inlIter->second.begin(); + while (pmlIter != inlIter->second.end()) { + if ((*pmlIter)->type & type) { + related.push_back(*pmlIter); + } + pmlIter++; + } + inlIter++; + } + return related; + +} + +} \ No newline at end of file diff --git a/src/uscxml/transform/promela/PromelaInlines.h b/src/uscxml/transform/promela/PromelaInlines.h new file mode 100644 index 0000000..2621f8d --- /dev/null +++ b/src/uscxml/transform/promela/PromelaInlines.h @@ -0,0 +1,113 @@ +/** + * @file + * @author 2016 Stefan Radomski (stefan.radomski@cs.tu-darmstadt.de) + * @copyright Simplified BSD + * + * @cond + * This program is free software: you can redistribute it and/or modify + * it under the terms of the FreeBSD license as published by the FreeBSD + * project. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * You should have received a copy of the FreeBSD license along with this + * program. If not, see . + * @endcond + */ + +#ifndef PROMELAINLINES_H_29BF8EF3 +#define PROMELAINLINES_H_29BF8EF3 + +#include "uscxml/config.h" +#include "uscxml/Common.h" +#include "uscxml/messages/Data.h" +#include "uscxml/util/DOM.h" + +#include +#include +#include + +namespace uscxml { + +class USCXML_API PromelaInline { +public: + enum PromelaInlineType { + PROMELA_NIL = 0x0000, + PROMELA_LTL = 0x0001, + PROMELA_CODE = 0x0002, + PROMELA_EVENT_ALL_BUT = 0x0004, + PROMELA_EVENT_ONLY = 0x0008, + PROMELA_PROGRESS_LABEL = 0x0010, + PROMELA_ACCEPT_LABEL = 0x0020, + PROMELA_END_LABEL = 0x0040 + }; + + PromelaInline(const XERCESC_NS::DOMNode* node); + virtual ~PromelaInline() {} + + operator bool() { + return (type != PROMELA_NIL); + } + + std::list children; + PromelaInline* prevSibling; + PromelaInline* nextSibling; + + virtual void dump(); + + virtual bool relatesTo(const XERCESC_NS::DOMNode* node) { + return container == node; + } + + size_t level; + std::string content; + const XERCESC_NS::DOMElement* container; + PromelaInlineType type; + +protected: + PromelaInline() : prevSibling(NULL), nextSibling(NULL), type(PROMELA_NIL) {}; +}; + + +class USCXML_API PromelaEventSource : public PromelaInline { +public: + PromelaEventSource(const PromelaInline& pmlInline) { + type = pmlInline.type; + container = pmlInline.container; + content = pmlInline.content; + events = Data::fromJSON(pmlInline.content); + } + + virtual bool relatesTo(const XERCESC_NS::DOMNode* node) { + return container == node || DOMUtils::isDescendant(node, container); + } + + Data events; +}; + + +class USCXML_API PromelaInlines { +public: + + PromelaInlines(const XERCESC_NS::DOMNode* node); + PromelaInlines() {} + + virtual ~PromelaInlines(); + + std::list getRelatedTo(const XERCESC_NS::DOMNode* node, PromelaInline::PromelaInlineType type); + std::list getAllOfType(uint32_t type); + + std::map > inlines; + std::list allInlines; + + static std::list getStringLiterals(const Data& data); + static std::list getEventNames(const Data& data); + + +}; + +} + +#endif /* end of include guard: PROMELAINLINES_H_29BF8EF3 */ diff --git a/src/uscxml/util/DOM.cpp b/src/uscxml/util/DOM.cpp index 7793fb5..1de6423 100644 --- a/src/uscxml/util/DOM.cpp +++ b/src/uscxml/util/DOM.cpp @@ -236,13 +236,13 @@ void DOMUtils::inPostFixOrder(const std::set& elements, if (root == NULL) return; - for (auto childElem = root->getFirstElementChild(); childElem; childElem = childElem->getNextElementSibling()) { + for (auto childElem = root->getFirstElementChild(); childElem; childElem = childElem->getNextElementSibling()) { if (!includeEmbeddedDoc && LOCALNAME(childElem) == "scxml") continue; inPostFixOrder(elements, childElem, includeEmbeddedDoc, nodes); } - for (auto childElem = root->getFirstElementChild(); childElem; childElem = childElem->getNextElementSibling()) { + for (auto childElem = root->getFirstElementChild(); childElem; childElem = childElem->getNextElementSibling()) { if (!includeEmbeddedDoc && TAGNAME(childElem) == XML_PREFIX(root).str() + "scxml") continue; @@ -271,14 +271,14 @@ void DOMUtils::inDocumentOrder(const std::set& elements, nodes.push_back((DOMElement*)root); } - /// @todo: item from getChildNodes is O(N)! - DOMElement* child = root->getFirstElementChild(); - while(child) { - if (includeEmbeddedDoc || TAGNAME(child) != XML_PREFIX(root).str() + "scxml") { - inDocumentOrder(elements, child, includeEmbeddedDoc, nodes); - } + /// @todo: item from getChildNodes is O(N)! + DOMElement* child = root->getFirstElementChild(); + while(child) { + if (includeEmbeddedDoc || TAGNAME(child) != XML_PREFIX(root).str() + "scxml") { + inDocumentOrder(elements, child, includeEmbeddedDoc, nodes); + } - child = child->getNextElementSibling(); + child = child->getNextElementSibling(); } } @@ -343,7 +343,7 @@ std::list DOMUtils::filterChildElements(const std::string& tagName, if (!node) return filteredChildElems; - for (auto childElem = node->getFirstElementChild(); childElem; childElem = childElem->getNextElementSibling()) { + for (auto childElem = node->getFirstElementChild(); childElem; childElem = childElem->getNextElementSibling()) { // std::cerr << TAGNAME(childs.item(i)) << std::endl; if(iequals(TAGNAME(childElem), tagName)) { filteredChildElems.push_back((DOMElement*)childElem); @@ -379,7 +379,7 @@ std::list DOMUtils::filterChildType(const DOMNode::NodeType type, if (!node) return filteredChildTypes; - for (auto child = node->getFirstChild(); child; child = child->getNextSibling()) { + for (auto child = node->getFirstChild(); child; child = child->getNextSibling()) { if (child->getNodeType() == type) filteredChildTypes.push_back(child); if (recurse) { diff --git a/src/uscxml/util/DOM.h b/src/uscxml/util/DOM.h index ae5fa60..e8094cf 100644 --- a/src/uscxml/util/DOM.h +++ b/src/uscxml/util/DOM.h @@ -159,7 +159,7 @@ public : } X(const char* const fromTranscode) { - + // Call the private transcoding method _localForm = fromTranscode; _unicodeForm = XERCESC_NS::XMLString::transcode(fromTranscode); @@ -168,24 +168,24 @@ public : X(char* fromTranscode) { - // Call the private transcoding method + // Call the private transcoding method _localForm = fromTranscode; _unicodeForm = XERCESC_NS::XMLString::transcode(fromTranscode); _deallocOther = true; } X() { - + _unicodeForm = NULL; _deallocOther = false; } ~X() { - + if (_deallocOther) XERCESC_NS::XMLString::release(&_unicodeForm); } - + const std::string& str() const { return _localForm; } @@ -202,7 +202,7 @@ public : operator std::string () { return _localForm; } - + protected: friend USCXML_API std::ostream& operator<< (std::ostream& os, const X& data); @@ -211,76 +211,76 @@ private: std::string _localForm; XMLCh* _unicodeForm; }; - + #else class USCXML_API X { public : - X() { - } - - void operator=(X const &other) { - localForm = other.localForm; - if (unicodeForm != NULL) { - XERCESC_NS::XMLString::release(&unicodeForm); - } - unicodeForm = XERCESC_NS::XMLString::replicate(other.unicodeForm); - } - - X(X const &other) { - localForm = other.localForm; - unicodeForm = XERCESC_NS::XMLString::replicate(other.unicodeForm); - } - - X(const char* const toTranscode) { - if (toTranscode != NULL) { - localForm = toTranscode; - unicodeForm = XERCESC_NS::XMLString::transcode(toTranscode); - } - } - - X(const XMLCh* toTranscode) { - if (toTranscode != NULL) { - unicodeForm = XERCESC_NS::XMLString::replicate(toTranscode); - localForm = XERCESC_NS::XMLString::transcode(toTranscode); - } - } - - X(const std::string& toTranscode) { - localForm = toTranscode; - unicodeForm = XERCESC_NS::XMLString::transcode(toTranscode.c_str()); - } - - ~X() { - if (unicodeForm != NULL) { - XERCESC_NS::XMLString::release(&unicodeForm); - } - } - - operator XMLCh* () const { - return unicodeForm; - } - - operator const std::string& () { - return localForm; - } - - const std::string& str() const { - return localForm; - } - - const XMLCh* unicode() const { - return unicodeForm; - } + X() { + } + + void operator=(X const &other) { + localForm = other.localForm; + if (unicodeForm != NULL) { + XERCESC_NS::XMLString::release(&unicodeForm); + } + unicodeForm = XERCESC_NS::XMLString::replicate(other.unicodeForm); + } + + X(X const &other) { + localForm = other.localForm; + unicodeForm = XERCESC_NS::XMLString::replicate(other.unicodeForm); + } + + X(const char* const toTranscode) { + if (toTranscode != NULL) { + localForm = toTranscode; + unicodeForm = XERCESC_NS::XMLString::transcode(toTranscode); + } + } + + X(const XMLCh* toTranscode) { + if (toTranscode != NULL) { + unicodeForm = XERCESC_NS::XMLString::replicate(toTranscode); + localForm = XERCESC_NS::XMLString::transcode(toTranscode); + } + } + + X(const std::string& toTranscode) { + localForm = toTranscode; + unicodeForm = XERCESC_NS::XMLString::transcode(toTranscode.c_str()); + } + + ~X() { + if (unicodeForm != NULL) { + XERCESC_NS::XMLString::release(&unicodeForm); + } + } + + operator XMLCh* () const { + return unicodeForm; + } + + operator const std::string& () { + return localForm; + } + + const std::string& str() const { + return localForm; + } + + const XMLCh* unicode() const { + return unicodeForm; + } protected: - friend USCXML_API std::ostream& operator<< (std::ostream& os, const X& data); + friend USCXML_API std::ostream& operator<< (std::ostream& os, const X& data); private: - XMLCh* unicodeForm = NULL; - std::string localForm; - + XMLCh* unicodeForm = NULL; + std::string localForm; + }; #endif @@ -295,14 +295,14 @@ static const X kElementFinalName = X("final"); static const X kElementOnEntryName = X("onentry"); static const X kElementOnExitName = X("onexit"); static const X kElementHistoryName = X("history"); - + static const X kElementRaiseName = X("raise"); static const X kElementIfName = X("if"); static const X kElementElseIfName = X("elseif"); static const X kElementElseName = X("else"); static const X kElementForEachName = X("foreach"); static const X kElementLogName = X("log"); - + static const X kElementDataModelName = X("datamodel"); static const X kElementDataName = X("data"); static const X kElementAssignName = X("assign"); @@ -310,7 +310,7 @@ static const X kElementContentName = X("content"); static const X kElementParamName = X("param"); static const X kElementScriptName = X("script"); #endif - + USCXML_API std::ostream& operator<< (std::ostream& os, const X& xmlString); USCXML_API std::ostream& operator<< (std::ostream& os, const XERCESC_NS::DOMNode& node); diff --git a/src/uscxml/util/Predicates.cpp b/src/uscxml/util/Predicates.cpp index 006e8dc..af47c68 100644 --- a/src/uscxml/util/Predicates.cpp +++ b/src/uscxml/util/Predicates.cpp @@ -27,7 +27,7 @@ using namespace XERCESC_NS; std::list getChildStates(const DOMElement* state, bool properOnly) { std::list children; - for (auto childElem = state->getFirstElementChild(); childElem; childElem = childElem->getNextElementSibling()) { + for (auto childElem = state->getFirstElementChild(); childElem; childElem = childElem->getNextElementSibling()) { if (isState(childElem, properOnly)) { children.push_back(childElem); } @@ -70,14 +70,14 @@ DOMElement* getSourceState(const DOMElement* transition) { #define VERBOSE_FIND_LCCA 0 DOMElement* findLCCA(const std::list& states) { - + std::list ancestors = getProperAncestors(states.front(), NULL); DOMElement* ancestor = NULL; #if VERBOSE_FIND_LCCA - std::cout << "states: " << states.size() << std::endl; - std::cout << "front: " << DOMUtils::xPathForNode(states.front()) << std::endl; - std::cout << "ancestors: " << ancestors.size() << std::endl; + std::cout << "states: " << states.size() << std::endl; + std::cout << "front: " << DOMUtils::xPathForNode(states.front()) << std::endl; + std::cout << "ancestors: " << ancestors.size() << std::endl; #endif for (auto ancIter = ancestors.begin(); ancIter != ancestors.end(); ancIter++) { @@ -121,8 +121,8 @@ std::list getProperAncestors(const DOMElement* s1, const DOMElement std::list ancestors; if (isState(s1, false)) { - // is it correct to also consider pseudo-states? - // gcc bug in findLCCA with test387, test388, test579, test580 otherwise + // is it correct to also consider pseudo-states? + // gcc bug in findLCCA with test387, test388, test579, test580 otherwise DOMNode* node = (DOMNode*)s1; while((node = node->getParentNode())) { if (node->getNodeType() != DOMNode::ELEMENT_NODE) @@ -133,8 +133,8 @@ std::list getProperAncestors(const DOMElement* s1, const DOMElement break; if (!iequals(LOCALNAME(nodeElem), "parallel") && - !iequals(LOCALNAME(nodeElem), "state") && - !iequals(LOCALNAME(nodeElem), "scxml")) + !iequals(LOCALNAME(nodeElem), "state") && + !iequals(LOCALNAME(nodeElem), "scxml")) break; if (node == s2) break; @@ -172,11 +172,11 @@ std::list getExitSet(const DOMElement* transition, const DOMElement bool conflicts(const DOMElement* t1, const DOMElement* t2, const DOMElement* root) { return ( - (getSourceState(t1) == getSourceState(t2)) || - (DOMUtils::isDescendant(getSourceState(t1), getSourceState(t2))) || - (DOMUtils::isDescendant(getSourceState(t2), getSourceState(t1))) || - (DOMUtils::hasIntersection(getExitSet(t1, root), getExitSet(t2, root))) - ); + (getSourceState(t1) == getSourceState(t2)) || + (DOMUtils::isDescendant(getSourceState(t1), getSourceState(t2))) || + (DOMUtils::isDescendant(getSourceState(t2), getSourceState(t1))) || + (DOMUtils::hasIntersection(getExitSet(t1, root), getExitSet(t2, root))) + ); } bool isState(const DOMElement* state, bool properOnly) { @@ -290,7 +290,7 @@ DOMElement* getTransitionDomain(const DOMElement* transition, const DOMElement* BREAK_LOOP: tStates.push_front(source); - + return findLCCA(tStates); } @@ -370,7 +370,7 @@ std::list getInitialStates(const DOMElement* state, const DOMElemen // first child state std::list initStates; - for (auto childElem = state->getFirstElementChild(); childElem; childElem = childElem->getNextElementSibling()) { + for (auto childElem = state->getFirstElementChild(); childElem; childElem = childElem->getNextElementSibling()) { if (isState(childElem)) { initStates.push_back(childElem); return initStates; @@ -461,24 +461,24 @@ std::list getReachableStates(const DOMElement* root) { bool areFromSameMachine(const DOMNode* n1, const DOMNode* n2) { - // we traverse each nodes parent's until we reach an scxml element or null + // we traverse each nodes parent's until we reach an scxml element or null const DOMNode* p1 = n1; while(p1) { if(iequals(LOCALNAME(p1), "scxml")) { - break; + break; } p1 = p1->getParentNode(); } - const DOMNode* p2 = n2; - while(p2) { - if(iequals(LOCALNAME(p2), "scxml")) { - break; - } - p2 = p2->getParentNode(); - } + const DOMNode* p2 = n2; + while(p2) { + if(iequals(LOCALNAME(p2), "scxml")) { + break; + } + p2 = p2->getParentNode(); + } - return p1 == p2; + return p1 == p2; } } \ No newline at end of file diff --git a/src/uscxml/util/URL.cpp b/src/uscxml/util/URL.cpp index 23b9854..79a0ad9 100644 --- a/src/uscxml/util/URL.cpp +++ b/src/uscxml/util/URL.cpp @@ -118,8 +118,8 @@ URLImpl::URLImpl(const std::string& url) : _orig(url), _handle(NULL), _requestTy URLImpl::~URLImpl() { uriFreeUriMembersA(&_uri); - if (_handle != NULL) - curl_easy_cleanup(_handle); + if (_handle != NULL) + curl_easy_cleanup(_handle); } URL URLImpl::resolve(URLImpl* relative, URLImpl* absolute) { @@ -592,7 +592,7 @@ void URLFetcher::fetchURL(URL& url) { char* header = (char*)malloc(paramIter->first.size() + strlen(value) + 3); sprintf(header,"%s: %s", paramIter->first.c_str(), value); headers = curl_slist_append(headers, header); - free(header); + free(header); // curl_free(key); // curl_free(value); paramIter++; @@ -600,9 +600,9 @@ void URLFetcher::fetchURL(URL& url) { // Disable "Expect: 100-continue" headers = curl_slist_append(headers, "Expect:"); - instance->_handlesToHeaders[handle] = headers; + instance->_handlesToHeaders[handle] = headers; - (curlError = curl_easy_setopt(handle, CURLOPT_HTTPHEADER, headers)) == CURLE_OK || + (curlError = curl_easy_setopt(handle, CURLOPT_HTTPHEADER, headers)) == CURLE_OK || LOG(ERROR) << "Cannot headers for " << std::string(url) << ": " << curl_easy_strerror(curlError); // curl_slist_free_all(headers); @@ -632,10 +632,10 @@ void URLFetcher::breakURL(URL& url) { curl_multi_remove_handle(instance->_multiHandle, handle); instance->_handlesToURLs.erase(handle); } - if (instance->_handlesToHeaders.find(handle) != instance->_handlesToHeaders.end()) { - curl_slist_free_all(instance->_handlesToHeaders[handle]); - instance->_handlesToHeaders.erase(handle); - } + if (instance->_handlesToHeaders.find(handle) != instance->_handlesToHeaders.end()) { + curl_slist_free_all(instance->_handlesToHeaders[handle]); + instance->_handlesToHeaders.erase(handle); + } } void URLFetcher::start() { @@ -759,13 +759,13 @@ void URLFetcher::perform() { if (err != CURLM_OK) { LOG(WARNING) << "curl_multi_remove_handle: " << curl_multi_strerror(err); } - break; + break; } - _handlesToURLs.erase(msg->easy_handle); - curl_slist_free_all(_handlesToHeaders[msg->easy_handle]); - _handlesToHeaders.erase(msg->easy_handle); - + _handlesToURLs.erase(msg->easy_handle); + curl_slist_free_all(_handlesToHeaders[msg->easy_handle]); + _handlesToHeaders.erase(msg->easy_handle); + } else { LOG(ERROR) << "Curl reports info on unfinished download?!"; } diff --git a/src/uscxml/util/URL.h b/src/uscxml/util/URL.h index 2b5c9e0..f6da30d 100644 --- a/src/uscxml/util/URL.h +++ b/src/uscxml/util/URL.h @@ -325,7 +325,7 @@ protected: bool _isStarted; std::map _handlesToURLs; - std::map _handlesToHeaders; + std::map _handlesToHeaders; CURLM* _multiHandle; char* _envProxy; }; diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index e14586c..b0c5114 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -32,8 +32,7 @@ USCXML_TEST_COMPILE(NAME test-snippets LABEL general/test-snippets FILES src/tes # USCXML_TEST_COMPILE(NAME test-c89-parser LABEL general/test-c89-parser FILES src/test-c89-parser.cpp) # test-stress is not an automated test -add_executable(test-stress src/test-stress.cpp) -target_link_libraries(test-stress uscxml) +USCXML_TEST_COMPILE(BUILD_ONLY NAME test-stress LABEL general/test-stress FILES src/test-stress.cpp) file(GLOB_RECURSE USCXML_WRAPPERS ${PROJECT_SOURCE_DIR}/src/bindings/swig/wrapped/*.cpp @@ -41,6 +40,8 @@ file(GLOB_RECURSE USCXML_WRAPPERS ) USCXML_TEST_COMPILE(NAME test-bindings LABEL general/test-bindings FILES ${USCXML_WRAPPERS} src/test-bindings.cpp) +USCXML_TEST_COMPILE(NAME test-promela-parser LABEL general/test-promela-parser FILES src/test-promela-parser.cpp) +target_link_libraries(test-promela-parser uscxml_transform) # the one binary to test for pass / fail final states add_executable(test-state-pass src/test-state-pass.cpp ${GETOPT_FILES}) @@ -134,14 +135,14 @@ if (NOT BUILD_MINIMAL) "null" "lua" "c89" - # "promela" + "promela" # generated c source "gen/c/ecma" # "gen/c/xpath" "gen/c/lua" # "gen/c/promela" - # "gen/vhdl/ecma" + "gen/vhdl/ecma" # bindings "binding/java/jexl" @@ -153,7 +154,7 @@ if (NOT BUILD_MINIMAL) # "fsm/promela" # formal verification - # "spin/promela" + "spin/promela" # performance tests # "perf/gen/c/ecma" diff --git a/test/bindings/java/org/uscxml/apache/commons/scxml2/JexlEvaluator.java b/test/bindings/java/org/uscxml/apache/commons/scxml2/JexlEvaluator.java index e50a259..127bed3 100644 --- a/test/bindings/java/org/uscxml/apache/commons/scxml2/JexlEvaluator.java +++ b/test/bindings/java/org/uscxml/apache/commons/scxml2/JexlEvaluator.java @@ -1,7 +1,7 @@ package org.uscxml.apache.commons.scxml2; import org.uscxml.Factory; -import org.uscxml.dm.jexl.JEXLDataModel; +import org.uscxml.dm.jexl.JexlDataModel; public class JexlEvaluator extends Evaluator { @@ -13,7 +13,7 @@ public class JexlEvaluator extends Evaluator { public Context newContext(Object object) { // TODO Auto-generated method stub Context ctx = new Context(); - ctx.dm = new JEXLDataModel(); + ctx.dm = new JexlDataModel(); return ctx; } } diff --git a/test/bindings/java/org/uscxml/dm/jexl/JEXLDataModel.java b/test/bindings/java/org/uscxml/dm/jexl/JEXLDataModel.java index 5564d63..cd9d175 100644 --- a/test/bindings/java/org/uscxml/dm/jexl/JEXLDataModel.java +++ b/test/bindings/java/org/uscxml/dm/jexl/JEXLDataModel.java @@ -10,7 +10,6 @@ import java.util.Map; import java.util.Set; import org.apache.commons.jexl3.JexlBuilder; -import org.apache.commons.jexl3.JexlContext; import org.apache.commons.jexl3.JexlEngine; import org.apache.commons.jexl3.JexlException; import org.apache.commons.jexl3.JexlExpression; @@ -19,18 +18,22 @@ import org.uscxml.Data; import org.uscxml.DataList; import org.uscxml.DataMap; import org.uscxml.DataModel; +import org.uscxml.DataModelExtension; import org.uscxml.ErrorEvent; import org.uscxml.Event; import org.uscxml.StringList; import org.uscxml.StringVector; -public class JEXLDataModel extends DataModel { +public class JexlDataModel extends DataModel { protected static final JexlEngine jexl = new JexlBuilder().cache(512).strict(true).silent(false).create(); - protected JexlContext ctx; - - - + public MapContext ctx = new MapContext(); + + @Override + public void addExtension(DataModelExtension ext) { + throw new UnsupportedOperationException("Cannot add extensions to the jexl datamodel"); + } + @Override public StringList getNames() { StringList names = new StringList(); @@ -40,8 +43,7 @@ public class JEXLDataModel extends DataModel { @Override public DataModel create() { - JEXLDataModel dm = new JEXLDataModel(); - dm.ctx = new MapContext(); + JexlDataModel dm = new JexlDataModel(); return dm; } @@ -73,10 +75,9 @@ public class JEXLDataModel extends DataModel { @Override public Data evalAsData(String content) { JexlExpression expr = jexl.createExpression(content); - System.out.println(); - Data d = new Data(); - d.setAtom(expr.getParsedText()); - d.setType(Data.Type.VERBATIM); + Data d = getJexlObjectAsData(expr.evaluate(ctx)); +// d.setAtom(expr.getParsedText()); +// d.setType(Data.Type.VERBATIM); return d; } diff --git a/test/bindings/java/org/uscxml/examples/DataModelExample.java b/test/bindings/java/org/uscxml/examples/DataModelExample.java index e6ad619..bba64eb 100644 --- a/test/bindings/java/org/uscxml/examples/DataModelExample.java +++ b/test/bindings/java/org/uscxml/examples/DataModelExample.java @@ -7,7 +7,7 @@ import org.uscxml.Factory; import org.uscxml.Interpreter; import org.uscxml.InterpreterException; import org.uscxml.InterpreterState; -import org.uscxml.dm.jexl.JEXLDataModel; +import org.uscxml.dm.jexl.JexlDataModel; import org.uscxml.helper.TestMonitor; public class DataModelExample { @@ -20,7 +20,7 @@ public class DataModelExample { System.load(uSCXMLLibPath); - JEXLDataModel jdm = new JEXLDataModel(); + JexlDataModel jdm = new JexlDataModel(); Factory.getInstance().registerDataModel(jdm);; TestMonitor tm = new TestMonitor(); diff --git a/test/bindings/java/org/uscxml/helper/StopWatch.java b/test/bindings/java/org/uscxml/helper/StopWatch.java new file mode 100644 index 0000000..4123ba1 --- /dev/null +++ b/test/bindings/java/org/uscxml/helper/StopWatch.java @@ -0,0 +1,22 @@ +package org.uscxml.helper; + +import org.uscxml.Data; +import org.uscxml.DataModelExtension; + +public class StopWatch { + + public StopWatch() { + } + + public void reset() { + System.out.println("RESET"); + } + + public void start() { + System.out.println("START"); + } + public void stop() { + System.out.println("STOP"); + } + +} diff --git a/test/bindings/java/org/uscxml/tests/JexlDataModelTest.java b/test/bindings/java/org/uscxml/tests/JexlDataModelTest.java index 876feb2..da79d37 100644 --- a/test/bindings/java/org/uscxml/tests/JexlDataModelTest.java +++ b/test/bindings/java/org/uscxml/tests/JexlDataModelTest.java @@ -3,11 +3,13 @@ package org.uscxml.tests; import java.io.File; import java.net.MalformedURLException; +import org.uscxml.ActionLanguage; import org.uscxml.Factory; import org.uscxml.Interpreter; import org.uscxml.InterpreterException; import org.uscxml.InterpreterState; -import org.uscxml.dm.jexl.JEXLDataModel; +import org.uscxml.dm.jexl.JexlDataModel; +import org.uscxml.helper.StopWatch; import org.uscxml.helper.TestMonitor; public class JexlDataModelTest { @@ -19,26 +21,37 @@ public class JexlDataModelTest { } System.load(uSCXMLLibPath); - String testUri = "/Users/sradomski/Documents/TK/Code/uscxml/test/w3c/jexl/test144.scxml"; +// String testUri = "/Users/sradomski/Documents/TK/Code/uscxml/test/w3c/jexl/test144.scxml"; +// String testUri = "/Users/sradomski/Desktop/stopwatch.xml"; - if (args.length > 0) { - testUri = args[0]; - } + +// if (args.length > 0) { +// testUri = args[0]; +// } { - JEXLDataModel jdm = new JEXLDataModel(); - Factory.getInstance().registerDataModel(jdm); + JexlDataModel jdm = new JexlDataModel(); +// Factory.getInstance().registerDataModel(jdm); + TestMonitor tm = new TestMonitor(); try { - File testFile = new File(testUri); - String testName = testFile.toURI().toURL().toString(); +// File testFile = new File(testUri); +// String testName = testFile.toURI().toURL().toString(); + String testName = "https://raw.githubusercontent.com/woonsan/commons-scxml-examples/master/stopwatch/src/main/resources/com/github/woonsan/commons/scxml/examples/stopwatch/stopwatch.xml"; System.out.println(testName); Interpreter scxml = Interpreter.fromURL(testName); + + jdm.ctx.set("stopWatch", new StopWatch()); + + ActionLanguage al = new ActionLanguage(); + al.setDataModel(jdm); + scxml.setActionLanguage(al); + scxml.addMonitor(tm); - + while (scxml.step() != InterpreterState.USCXML_FINISHED) { } @@ -48,7 +61,7 @@ public class JexlDataModelTest { } System.out.println("SUCCESS"); - } catch (InterpreterException | MalformedURLException e) { + } catch (InterpreterException e) { e.printStackTrace(); System.exit(-1); } diff --git a/test/ctest/scripts/run_promela_test.cmake b/test/ctest/scripts/run_promela_test.cmake index 818cf66..271434f 100644 --- a/test/ctest/scripts/run_promela_test.cmake +++ b/test/ctest/scripts/run_promela_test.cmake @@ -20,10 +20,10 @@ if(CMD_RESULT) endif() message(STATUS "time for transforming to c") -message(STATUS "${CXX_BIN} -DMEMLIM=1024 -DVECTORSZ=8192 -O2 -DXUSAFE -w -o ${OUTDIR}/pan ${OUTDIR}/pan.c") -execute_process(COMMAND time -p ${CXX_BIN} -DMEMLIM=1024 -DVECTORSZ=8192 -O2 -DXUSAFE -w -o ${OUTDIR}/pan ${OUTDIR}/pan.c WORKING_DIRECTORY ${OUTDIR} RESULT_VARIABLE CMD_RESULT) +message(STATUS "${CC_BIN} -DMEMLIM=1024 -DVECTORSZ=8192 -O2 -DXUSAFE -w -o ${OUTDIR}/pan ${OUTDIR}/pan.c") +execute_process(COMMAND time -p ${CC_BIN} -DMEMLIM=1024 -DVECTORSZ=8192 -O2 -DXUSAFE -w -o ${OUTDIR}/pan ${OUTDIR}/pan.c WORKING_DIRECTORY ${OUTDIR} RESULT_VARIABLE CMD_RESULT) if(CMD_RESULT) - message(FATAL_ERROR "Error running gcc ${CXX_BIN}: ${CMD_RESULT}") + message(FATAL_ERROR "Error running gcc ${CC_BIN}: ${CMD_RESULT}") endif() message(STATUS "time for transforming to binary") diff --git a/test/src/test-bindings.cpp b/test/src/test-bindings.cpp index 6932f67..61ed2d4 100644 --- a/test/src/test-bindings.cpp +++ b/test/src/test-bindings.cpp @@ -7,5 +7,5 @@ int main() { - return 0; + return 0; } \ No newline at end of file diff --git a/test/src/test-c89-parser.cpp b/test/src/test-c89-parser.cpp index 9a4d570..11a1564 100644 --- a/test/src/test-c89-parser.cpp +++ b/test/src/test-c89-parser.cpp @@ -13,104 +13,104 @@ void testC89Parser() { c89_debug = 0; - std::list localTest = { - "int main() { a = 10; }" - }; - - for (auto test : localTest) { - try { - C89Parser ast(test); - ast.dump(); - } catch (Event e) { - std::cerr << e << std::endl; - } - } + std::list localTest = { + "int main() { a = 10; }" + }; - assert(false); - - std::list remoteTests = { - URL("https://raw.githubusercontent.com/zsaleeba/picoc/master/tests/00_assignment.c"), - URL("https://raw.githubusercontent.com/zsaleeba/picoc/master/tests/01_comment.c"), - URL("https://raw.githubusercontent.com/zsaleeba/picoc/master/tests/02_printf.c"), - URL("https://raw.githubusercontent.com/zsaleeba/picoc/master/tests/03_struct.c"), - URL("https://raw.githubusercontent.com/zsaleeba/picoc/master/tests/04_for.c"), - URL("https://raw.githubusercontent.com/zsaleeba/picoc/master/tests/05_array.c"), - URL("https://raw.githubusercontent.com/zsaleeba/picoc/master/tests/06_case.c"), - URL("https://raw.githubusercontent.com/zsaleeba/picoc/master/tests/07_function.c"), - URL("https://raw.githubusercontent.com/zsaleeba/picoc/master/tests/08_while.c"), - URL("https://raw.githubusercontent.com/zsaleeba/picoc/master/tests/09_do_while.c"), - URL("https://raw.githubusercontent.com/zsaleeba/picoc/master/tests/10_pointer.c"), - URL("https://raw.githubusercontent.com/zsaleeba/picoc/master/tests/11_precedence.c"), - URL("https://raw.githubusercontent.com/zsaleeba/picoc/master/tests/12_hashdefine.c"), - URL("https://raw.githubusercontent.com/zsaleeba/picoc/master/tests/13_integer_literals.c"), - URL("https://raw.githubusercontent.com/zsaleeba/picoc/master/tests/14_if.c"), - URL("https://raw.githubusercontent.com/zsaleeba/picoc/master/tests/15_recursion.c"), - URL("https://raw.githubusercontent.com/zsaleeba/picoc/master/tests/16_nesting.c"), - URL("https://raw.githubusercontent.com/zsaleeba/picoc/master/tests/17_enum.c"), - URL("https://raw.githubusercontent.com/zsaleeba/picoc/master/tests/18_include.c"), - URL("https://raw.githubusercontent.com/zsaleeba/picoc/master/tests/19_pointer_arithmetic.c"), - URL("https://raw.githubusercontent.com/zsaleeba/picoc/master/tests/20_pointer_comparison.c"), - URL("https://raw.githubusercontent.com/zsaleeba/picoc/master/tests/21_char_array.c"), - URL("https://raw.githubusercontent.com/zsaleeba/picoc/master/tests/22_floating_point.c"), - URL("https://raw.githubusercontent.com/zsaleeba/picoc/master/tests/23_type_coercion.c"), - URL("https://raw.githubusercontent.com/zsaleeba/picoc/master/tests/24_math_library.c"), - URL("https://raw.githubusercontent.com/zsaleeba/picoc/master/tests/25_quicksort.c"), - URL("https://raw.githubusercontent.com/zsaleeba/picoc/master/tests/26_character_constants.c"), - URL("https://raw.githubusercontent.com/zsaleeba/picoc/master/tests/27_sizeof.c"), - URL("https://raw.githubusercontent.com/zsaleeba/picoc/master/tests/28_strings.c"), - URL("https://raw.githubusercontent.com/zsaleeba/picoc/master/tests/29_array_address.c"), - URL("https://raw.githubusercontent.com/zsaleeba/picoc/master/tests/30_hanoi.c"), - URL("https://raw.githubusercontent.com/zsaleeba/picoc/master/tests/31_args.c"), - URL("https://raw.githubusercontent.com/zsaleeba/picoc/master/tests/32_led.c"), - URL("https://raw.githubusercontent.com/zsaleeba/picoc/master/tests/33_ternary_op.c"), - URL("https://raw.githubusercontent.com/zsaleeba/picoc/master/tests/34_array_assignment.c"), - URL("https://raw.githubusercontent.com/zsaleeba/picoc/master/tests/35_sizeof.c"), - URL("https://raw.githubusercontent.com/zsaleeba/picoc/master/tests/36_array_initialisers.c"), - URL("https://raw.githubusercontent.com/zsaleeba/picoc/master/tests/37_sprintf.c"), - URL("https://raw.githubusercontent.com/zsaleeba/picoc/master/tests/38_multiple_array_index.c"), - URL("https://raw.githubusercontent.com/zsaleeba/picoc/master/tests/39_typedef.c"), - URL("https://raw.githubusercontent.com/zsaleeba/picoc/master/tests/40_stdio.c"), - URL("https://raw.githubusercontent.com/zsaleeba/picoc/master/tests/41_hashif.c"), - URL("https://raw.githubusercontent.com/zsaleeba/picoc/master/tests/42_function_pointer.c"), - URL("https://raw.githubusercontent.com/zsaleeba/picoc/master/tests/43_void_param.c"), - URL("https://raw.githubusercontent.com/zsaleeba/picoc/master/tests/44_scoped_declarations.c"), - URL("https://raw.githubusercontent.com/zsaleeba/picoc/master/tests/45_empty_for.c"), - URL("https://raw.githubusercontent.com/zsaleeba/picoc/master/tests/46_grep.c"), - URL("https://raw.githubusercontent.com/zsaleeba/picoc/master/tests/47_switch_return.c"), - URL("https://raw.githubusercontent.com/zsaleeba/picoc/master/tests/48_nested_break.c"), - URL("https://raw.githubusercontent.com/zsaleeba/picoc/master/tests/49_bracket_evaluation.c"), - URL("https://raw.githubusercontent.com/zsaleeba/picoc/master/tests/50_logical_second_arg.c"), - URL("https://raw.githubusercontent.com/zsaleeba/picoc/master/tests/51_static.c"), - URL("https://raw.githubusercontent.com/zsaleeba/picoc/master/tests/52_unnamed_enum.c"), - URL("https://raw.githubusercontent.com/zsaleeba/picoc/master/tests/54_goto.c"), - URL("https://raw.githubusercontent.com/zsaleeba/picoc/master/tests/55_array_initialiser.c"), - URL("https://raw.githubusercontent.com/zsaleeba/picoc/master/tests/56_cross_structure.c"), - URL("https://raw.githubusercontent.com/zsaleeba/picoc/master/tests/57_macro_bug.c"), - URL("https://raw.githubusercontent.com/zsaleeba/picoc/master/tests/58_return_outside.c"), - URL("https://raw.githubusercontent.com/zsaleeba/picoc/master/tests/59_break_before_loop.c"), - URL("https://raw.githubusercontent.com/zsaleeba/picoc/master/tests/60_local_vars.c"), - URL("https://raw.githubusercontent.com/zsaleeba/picoc/master/tests/61_initializers.c"), - URL("https://raw.githubusercontent.com/zsaleeba/picoc/master/tests/62_float.c"), - URL("https://raw.githubusercontent.com/zsaleeba/picoc/master/tests/63_typedef.c"), - URL("https://raw.githubusercontent.com/zsaleeba/picoc/master/tests/64_double_prefix_op.c"), - URL("https://raw.githubusercontent.com/zsaleeba/picoc/master/tests/65_typeless.c"), - URL("https://raw.githubusercontent.com/zsaleeba/picoc/master/tests/66_printf_undefined.c"), - URL("https://raw.githubusercontent.com/zsaleeba/picoc/master/tests/67_macro_crash.c"), - URL("https://raw.githubusercontent.com/zsaleeba/picoc/master/tests/68_return.c") - }; - - for (auto testURL : remoteTests) { + for (auto test : localTest) { try { - std::cout << std::endl << "'" << (std::string)testURL << "':" << std::endl; - std::cout << testURL.getInContent() << std::endl; - + C89Parser ast(test); + ast.dump(); + } catch (Event e) { + std::cerr << e << std::endl; + } + } + + assert(false); + + std::list remoteTests = { + URL("https://raw.githubusercontent.com/zsaleeba/picoc/master/tests/00_assignment.c"), + URL("https://raw.githubusercontent.com/zsaleeba/picoc/master/tests/01_comment.c"), + URL("https://raw.githubusercontent.com/zsaleeba/picoc/master/tests/02_printf.c"), + URL("https://raw.githubusercontent.com/zsaleeba/picoc/master/tests/03_struct.c"), + URL("https://raw.githubusercontent.com/zsaleeba/picoc/master/tests/04_for.c"), + URL("https://raw.githubusercontent.com/zsaleeba/picoc/master/tests/05_array.c"), + URL("https://raw.githubusercontent.com/zsaleeba/picoc/master/tests/06_case.c"), + URL("https://raw.githubusercontent.com/zsaleeba/picoc/master/tests/07_function.c"), + URL("https://raw.githubusercontent.com/zsaleeba/picoc/master/tests/08_while.c"), + URL("https://raw.githubusercontent.com/zsaleeba/picoc/master/tests/09_do_while.c"), + URL("https://raw.githubusercontent.com/zsaleeba/picoc/master/tests/10_pointer.c"), + URL("https://raw.githubusercontent.com/zsaleeba/picoc/master/tests/11_precedence.c"), + URL("https://raw.githubusercontent.com/zsaleeba/picoc/master/tests/12_hashdefine.c"), + URL("https://raw.githubusercontent.com/zsaleeba/picoc/master/tests/13_integer_literals.c"), + URL("https://raw.githubusercontent.com/zsaleeba/picoc/master/tests/14_if.c"), + URL("https://raw.githubusercontent.com/zsaleeba/picoc/master/tests/15_recursion.c"), + URL("https://raw.githubusercontent.com/zsaleeba/picoc/master/tests/16_nesting.c"), + URL("https://raw.githubusercontent.com/zsaleeba/picoc/master/tests/17_enum.c"), + URL("https://raw.githubusercontent.com/zsaleeba/picoc/master/tests/18_include.c"), + URL("https://raw.githubusercontent.com/zsaleeba/picoc/master/tests/19_pointer_arithmetic.c"), + URL("https://raw.githubusercontent.com/zsaleeba/picoc/master/tests/20_pointer_comparison.c"), + URL("https://raw.githubusercontent.com/zsaleeba/picoc/master/tests/21_char_array.c"), + URL("https://raw.githubusercontent.com/zsaleeba/picoc/master/tests/22_floating_point.c"), + URL("https://raw.githubusercontent.com/zsaleeba/picoc/master/tests/23_type_coercion.c"), + URL("https://raw.githubusercontent.com/zsaleeba/picoc/master/tests/24_math_library.c"), + URL("https://raw.githubusercontent.com/zsaleeba/picoc/master/tests/25_quicksort.c"), + URL("https://raw.githubusercontent.com/zsaleeba/picoc/master/tests/26_character_constants.c"), + URL("https://raw.githubusercontent.com/zsaleeba/picoc/master/tests/27_sizeof.c"), + URL("https://raw.githubusercontent.com/zsaleeba/picoc/master/tests/28_strings.c"), + URL("https://raw.githubusercontent.com/zsaleeba/picoc/master/tests/29_array_address.c"), + URL("https://raw.githubusercontent.com/zsaleeba/picoc/master/tests/30_hanoi.c"), + URL("https://raw.githubusercontent.com/zsaleeba/picoc/master/tests/31_args.c"), + URL("https://raw.githubusercontent.com/zsaleeba/picoc/master/tests/32_led.c"), + URL("https://raw.githubusercontent.com/zsaleeba/picoc/master/tests/33_ternary_op.c"), + URL("https://raw.githubusercontent.com/zsaleeba/picoc/master/tests/34_array_assignment.c"), + URL("https://raw.githubusercontent.com/zsaleeba/picoc/master/tests/35_sizeof.c"), + URL("https://raw.githubusercontent.com/zsaleeba/picoc/master/tests/36_array_initialisers.c"), + URL("https://raw.githubusercontent.com/zsaleeba/picoc/master/tests/37_sprintf.c"), + URL("https://raw.githubusercontent.com/zsaleeba/picoc/master/tests/38_multiple_array_index.c"), + URL("https://raw.githubusercontent.com/zsaleeba/picoc/master/tests/39_typedef.c"), + URL("https://raw.githubusercontent.com/zsaleeba/picoc/master/tests/40_stdio.c"), + URL("https://raw.githubusercontent.com/zsaleeba/picoc/master/tests/41_hashif.c"), + URL("https://raw.githubusercontent.com/zsaleeba/picoc/master/tests/42_function_pointer.c"), + URL("https://raw.githubusercontent.com/zsaleeba/picoc/master/tests/43_void_param.c"), + URL("https://raw.githubusercontent.com/zsaleeba/picoc/master/tests/44_scoped_declarations.c"), + URL("https://raw.githubusercontent.com/zsaleeba/picoc/master/tests/45_empty_for.c"), + URL("https://raw.githubusercontent.com/zsaleeba/picoc/master/tests/46_grep.c"), + URL("https://raw.githubusercontent.com/zsaleeba/picoc/master/tests/47_switch_return.c"), + URL("https://raw.githubusercontent.com/zsaleeba/picoc/master/tests/48_nested_break.c"), + URL("https://raw.githubusercontent.com/zsaleeba/picoc/master/tests/49_bracket_evaluation.c"), + URL("https://raw.githubusercontent.com/zsaleeba/picoc/master/tests/50_logical_second_arg.c"), + URL("https://raw.githubusercontent.com/zsaleeba/picoc/master/tests/51_static.c"), + URL("https://raw.githubusercontent.com/zsaleeba/picoc/master/tests/52_unnamed_enum.c"), + URL("https://raw.githubusercontent.com/zsaleeba/picoc/master/tests/54_goto.c"), + URL("https://raw.githubusercontent.com/zsaleeba/picoc/master/tests/55_array_initialiser.c"), + URL("https://raw.githubusercontent.com/zsaleeba/picoc/master/tests/56_cross_structure.c"), + URL("https://raw.githubusercontent.com/zsaleeba/picoc/master/tests/57_macro_bug.c"), + URL("https://raw.githubusercontent.com/zsaleeba/picoc/master/tests/58_return_outside.c"), + URL("https://raw.githubusercontent.com/zsaleeba/picoc/master/tests/59_break_before_loop.c"), + URL("https://raw.githubusercontent.com/zsaleeba/picoc/master/tests/60_local_vars.c"), + URL("https://raw.githubusercontent.com/zsaleeba/picoc/master/tests/61_initializers.c"), + URL("https://raw.githubusercontent.com/zsaleeba/picoc/master/tests/62_float.c"), + URL("https://raw.githubusercontent.com/zsaleeba/picoc/master/tests/63_typedef.c"), + URL("https://raw.githubusercontent.com/zsaleeba/picoc/master/tests/64_double_prefix_op.c"), + URL("https://raw.githubusercontent.com/zsaleeba/picoc/master/tests/65_typeless.c"), + URL("https://raw.githubusercontent.com/zsaleeba/picoc/master/tests/66_printf_undefined.c"), + URL("https://raw.githubusercontent.com/zsaleeba/picoc/master/tests/67_macro_crash.c"), + URL("https://raw.githubusercontent.com/zsaleeba/picoc/master/tests/68_return.c") + }; + + for (auto testURL : remoteTests) { + try { + std::cout << std::endl << "'" << (std::string)testURL << "':" << std::endl; + std::cout << testURL.getInContent() << std::endl; + C89Parser ast(testURL.getInContent()); ast.dump(); - + } catch (Event e) { std::cerr << e << std::endl; } - std::this_thread::sleep_for(std::chrono::seconds(10)); + std::this_thread::sleep_for(std::chrono::seconds(10)); } } diff --git a/test/src/test-promela-parser.cpp b/test/src/test-promela-parser.cpp new file mode 100644 index 0000000..f0a019e --- /dev/null +++ b/test/src/test-promela-parser.cpp @@ -0,0 +1,323 @@ +#define protected public +#include "uscxml/util/URL.h" +#include "uscxml/Interpreter.h" +#include "uscxml/plugins/datamodel/promela/PromelaDataModel.h" +#include "uscxml/plugins/datamodel/promela/PromelaParser.h" +#include "uscxml/transform/ChartToPromela.h" +#include "uscxml/util/DOM.h" +#include "uscxml/util/Predicates.h" + +#include +#include + +#include +#include +#include + +using namespace uscxml; +using namespace XERCESC_NS; + +extern int promela_debug; + +void testInlinePromela() { + + + DOMImplementation *implementation = DOMImplementationRegistry::getDOMImplementation(X("LS")); + DOMDocument* document = implementation->createDocument(); + + { + std::string test = "\ + promela-code This is foo!\ + "; + + DOMComment* comment = document->createComment(X(test)); + PromelaInline inl(comment); + assert(inl.type == PromelaInline::PROMELA_CODE); + assert(inl.content == "This is foo!"); + } + + { + std::string test = "\ + promela-code\n \ + This is foo!\ + "; + + DOMComment* comment = document->createComment(X(test)); + PromelaInline inl(comment); + assert(inl.type == PromelaInline::PROMELA_CODE); + assert(inl.content == "This is foo!"); + } + + { + std::string test = "\ + promela-event\n \ + [{\"name\": \"e1\", \"data\": { \"foo\": \"some string\" }}, \ + {\"name\": \"e1\", \"data\": { \"bar\": 12 }}]"; + + DOMComment* comment = document->createComment(X(test)); + PromelaInline inl(comment); + assert(inl.type == PromelaInline::PROMELA_EVENT_ONLY); + + PromelaEventSource es(inl); + assert(es.events.array.size() == 2); + + } + + { + Interpreter interpreter = Interpreter::fromURL("/Users/sradomski/Documents/TK/Code/uscxml/test/uscxml/promela/test-event-source-auto.scxml"); + assert(interpreter); + PromelaInlines inls(interpreter.getImpl()->getDocument()->getDocumentElement()); + + assert(inls.getAllOfType(PromelaInline::PROMELA_EVENT_ONLY).size() == 2); + assert(inls.getAllOfType(PromelaInline::PROMELA_EVENT_ALL_BUT).size() == 1); + } + +#if 0 + { + std::string test = "\ + #promela-inline:\n \ + This is foo!\ + "; + PromelaInlines prmInls = PromelaInlines::fromString(test); + assert(prmInls.nrAcceptLabels == 0 && + prmInls.nrCodes == 1 && + prmInls.nrEventSources == 0 && + prmInls.nrEndLabels == 0 && + prmInls.nrAcceptLabels == 0 && + prmInls.nrProgressLabels == 0); + assert(prmInls.code.size() == 1); + assert(prmInls.code.front().type == PromelaInline::PROMELA_CODE); + assert(boost::trim_copy(prmInls.code.front().content) == "This is foo!"); + } + + { + std::string test = "#promela-progress"; + PromelaInlines prmInls = PromelaInlines::fromString(test); + assert(prmInls.nrAcceptLabels == 0 && + prmInls.nrCodes == 0 && + prmInls.nrEventSources == 0 && + prmInls.nrEndLabels == 0 && + prmInls.nrProgressLabels == 1); + assert(prmInls.code.size() == 1); + assert(prmInls.code.front().type == PromelaInline::PROMELA_PROGRESS_LABEL); + } + + { + std::string test = "#promela-accept and then some"; + PromelaInlines prmInls = PromelaInlines::fromString(test); + assert(prmInls.nrAcceptLabels == 1 && + prmInls.nrCodes == 0 && + prmInls.nrEventSources == 0 && + prmInls.nrEndLabels == 0 && + prmInls.nrProgressLabels == 0); + assert(prmInls.code.size() == 1); + assert(prmInls.code.front().type == PromelaInline::PROMELA_ACCEPT_LABEL); + } + + { + std::string test = "#promela-end and then some"; + PromelaInlines prmInls = PromelaInlines::fromString(test); + assert(prmInls.nrAcceptLabels == 0 && + prmInls.nrCodes == 0 && + prmInls.nrEventSources == 0 && + prmInls.nrEndLabels == 1 && + prmInls.nrProgressLabels == 0); + assert(prmInls.code.size() == 1); + assert(prmInls.code.front().type == PromelaInline::PROMELA_END_LABEL); + } + + { + std::string test = "\ + #promela-event-source:\n \ + This is foo!\ + "; + PromelaInlines prmInls = PromelaInlines::fromString(test); + assert(prmInls.nrAcceptLabels == 0 && + prmInls.nrCodes == 0 && + prmInls.nrEventSources == 1 && + prmInls.nrEndLabels == 0 && + prmInls.nrProgressLabels == 0); + assert(prmInls.code.size() == 1); + assert(prmInls.code.front().type == PromelaInline::PROMELA_EVENT_SOURCE); + + PromelaEventSource pmlES(prmInls.code.front()); + assert(pmlES.sequences.size() == 1); + std::list >::iterator seqsIter = pmlES.sequences.begin(); + std::list::iterator seqIter = seqsIter->begin(); + assert(*seqIter++ == "This"); + assert(*seqIter++ == "is"); + assert(*seqIter++ == "foo!"); + assert(seqIter == seqsIter->end()); + seqsIter++; + assert(seqsIter == pmlES.sequences.end()); + } + + { + std::string test = "\ + #promela-event-source:\n \ + This is foo!\n \ + This is bar!\n \ + "; + PromelaInlines prmInls = PromelaInlines::fromString(test); + assert(prmInls.nrAcceptLabels == 0 && + prmInls.nrCodes == 0 && + prmInls.nrEventSources == 1 && + prmInls.nrEndLabels == 0 && + prmInls.nrProgressLabels == 0); + assert(prmInls.code.size() == 1); + assert(prmInls.code.front().type == PromelaInline::PROMELA_EVENT_SOURCE); + + PromelaEventSource pmlES(prmInls.code.front()); + + assert(pmlES.sequences.size() == 2); + std::list >::iterator seqsIter = pmlES.sequences.begin(); + std::list::iterator seqIter = seqsIter->begin(); + assert(*seqIter++ == "This"); + assert(*seqIter++ == "is"); + assert(*seqIter++ == "foo!"); + assert(seqIter == seqsIter->end()); + seqsIter++; + seqIter = seqsIter->begin(); + assert(*seqIter++ == "This"); + assert(*seqIter++ == "is"); + assert(*seqIter++ == "bar!"); + assert(seqIter == seqsIter->end()); + seqsIter++; + assert(seqsIter == pmlES.sequences.end()); + } + + { + std::string test = "\ + #promela-event-source-custom:\n \ + This is foo!\ + "; + PromelaInlines prmInls = PromelaInlines::fromString(test); + assert(prmInls.nrAcceptLabels == 0 && + prmInls.nrCodes == 0 && + prmInls.nrEventSources == 1 && + prmInls.nrEndLabels == 0 && + prmInls.nrProgressLabels == 0); + assert(prmInls.code.size() == 1); + assert(prmInls.code.front().type == PromelaInline::PROMELA_EVENT_SOURCE_CUSTOM); + + PromelaEventSource pmlES(prmInls.code.front()); + + assert(pmlES.sequences.size() == 0); + assert(boost::trim_copy(pmlES.source.content) == "This is foo!"); + } + + { + std::string test = "\ + #promela-event-source-custom:\n \ + This is foo! \n\ + #promela-progress\ + "; + PromelaInlines prmInls = PromelaInlines::fromString(test); + assert(prmInls.nrAcceptLabels == 0 && + prmInls.nrCodes == 0 && + prmInls.nrEventSources == 1 && + prmInls.nrEndLabels == 0 && + prmInls.nrProgressLabels == 1); + assert(prmInls.code.size() == 2); + assert(prmInls.code.front().type == PromelaInline::PROMELA_EVENT_SOURCE_CUSTOM); + + PromelaEventSource pmlES(prmInls.code.front()); + + assert(pmlES.sequences.size() == 0); + assert(boost::trim_copy(pmlES.source.content) == "This is foo!"); + } +#endif +} + +void checkTokenLocations(const std::string& expr, PromelaParserNode* ast) { + if (ast->loc != NULL) { + assert(expr.substr(ast->loc->firstCol, ast->loc->lastCol - ast->loc->firstCol) == ast->value); + } + for (std::list::iterator opIter = ast->operands.begin(); opIter != ast->operands.end(); opIter++) { + checkTokenLocations(expr, *opIter); + } +} + +void testPromelaParser() { + + promela_debug = 0; +#if 1 + std::list expressions; + /* declarations */ + expressions.push_back("bool b1"); + expressions.push_back("bool b1;"); + expressions.push_back("bool b1, b2, b3"); + expressions.push_back("bool b1, b2, b3;"); + expressions.push_back("bool b1, b2 = 3 + 4, b3, b4, b5;"); + expressions.push_back("bool b1; bool b2; bool b3; bool b4;"); + expressions.push_back("bool b1; bool b2; bool b3, b4, b5;"); + expressions.push_back("bit b = 1;"); + expressions.push_back("byte state = 1;"); + expressions.push_back("bool b1, b2 = 1, b3;"); + 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.push_back("\n\n\n\n int foo = 3;\n\nint bar = 5;"); + + + /* expressions */ + expressions.push_back("i+1"); + expressions.push_back("(x == false || t == Bturn);"); + expressions.push_back("a + (1 << b)"); + expressions.push_back("(a + 1) << b"); + expressions.push_back("(b < N)"); + expressions.push_back("(mt+1)%MAX;"); + expressions.push_back("state[0] = state[3] + 5 * state[3*2/n]"); + + /* statements */ + expressions.push_back("t = Bturn;"); + 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("(n <= 1)"); + expressions.push_back("res = (a*a+b)/2*a;"); + expressions.push_back("assert(0) /* a forced stop, (Chapter 6) */"); + expressions.push_back("assert(count == 0 || count == 1)"); + expressions.push_back("busy[4 - 3] = 1;"); + + for (std::list::iterator exprIter = expressions.begin(); + exprIter != expressions.end(); + exprIter++) { + try { + std::cout << std::endl << "'" << *exprIter << "':" << std::endl; + PromelaParser ast(*exprIter); + ast.dump(); + if (!boost::contains(*exprIter, "\n")) + checkTokenLocations(*exprIter, ast.ast); + } catch (Event e) { + std::cerr << e << std::endl; + } + } +#endif + +} + +int main(int argc, char** argv) { + try { + ::xercesc_3_1::XMLPlatformUtils::Initialize(); + } catch (const XERCESC_NS::XMLException& toCatch) { + ERROR_PLATFORM_THROW("Cannot initialize XercesC: " + X(toCatch.getMessage()).str()); + } + + testInlinePromela(); + testPromelaParser(); +} \ No newline at end of file diff --git a/test/src/test-stress.cpp b/test/src/test-stress.cpp index 87000c8..d3209e2 100644 --- a/test/src/test-stress.cpp +++ b/test/src/test-stress.cpp @@ -24,21 +24,21 @@ class StatusMonitor : public uscxml::InterpreterMonitor { }; void printUsageAndExit() { - printf("test-stress version " USCXML_VERSION " (" CMAKE_BUILD_TYPE " build - " CMAKE_COMPILER_STRING ")\n"); - printf("Usage\n"); - printf("\ttest-stress"); + printf("test-stress version " USCXML_VERSION " (" CMAKE_BUILD_TYPE " build - " CMAKE_COMPILER_STRING ")\n"); + printf("Usage\n"); + printf("\ttest-stress"); #ifdef BUILD_AS_PLUGINS - printf(" [-p pluginPath]"); + printf(" [-p pluginPath]"); #endif - printf(" \n"); - printf("\n"); - exit(1); + printf(" \n"); + printf("\n"); + exit(1); } int main(int argc, char** argv) { using namespace uscxml; - if (argc < 2) { + if (argc < 2) { printUsageAndExit(); } @@ -62,7 +62,7 @@ int main(int argc, char** argv) { DirectoryWatch* watcher = new DirectoryWatch(argv[optind], true); watcher->updateEntries(true); - + std::map entries = watcher->getAllEntries(); StatusMonitor vm; @@ -77,27 +77,27 @@ int main(int argc, char** argv) { startedAt = time(NULL); lastTransitionAt = time(NULL); - Interpreter interpreter = Interpreter::fromURL(std::string(argv[optind]) + PATH_SEPERATOR + entryIter->first); + Interpreter interpreter = Interpreter::fromURL(std::string(argv[optind]) + PATH_SEPERATOR + entryIter->first); // Interpreter interpreter = Interpreter::fromURL("/Users/sradomski/Documents/TK/Code/uscxml/test/w3c/ecma/test422.scxml"); - LOG(INFO) << "Processing " << interpreter.getImpl()->getBaseURL(); + LOG(INFO) << "Processing " << interpreter.getImpl()->getBaseURL(); if (interpreter) { interpreter.addMonitor(&vm); - InterpreterState state = InterpreterState::USCXML_UNDEF; - int now = time(NULL); + InterpreterState state = InterpreterState::USCXML_UNDEF; + int now = time(NULL); - try { - while(state != USCXML_FINISHED && now - startedAt < 20 && now - lastTransitionAt < 2) { + try { + while(state != USCXML_FINISHED && now - startedAt < 20 && now - lastTransitionAt < 2) { // while(state != USCXML_FINISHED) { - state = interpreter.step(200); - now = time(NULL); - } - } catch (...) {} + state = interpreter.step(200); + now = time(NULL); + } + } catch (...) {} } entryIter++; - - // forever + + // forever // if (entryIter == entries.end()) { // entryIter = entries.begin(); // } @@ -105,5 +105,5 @@ int main(int argc, char** argv) { delete watcher; - return EXIT_SUCCESS; + return EXIT_SUCCESS; } \ No newline at end of file diff --git a/test/uscxml/promela/test-complete.scxml b/test/uscxml/promela/test-complete.scxml new file mode 100644 index 0000000..a96152b --- /dev/null +++ b/test/uscxml/promela/test-complete.scxml @@ -0,0 +1,154 @@ + + + + [1,2,3] + + { foo: 1, bar: 'baz' } + { itemSum: 0, indexSum: 0 } + + 0 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/test/uscxml/promela/test-event-source-auto.scxml b/test/uscxml/promela/test-event-source-auto.scxml new file mode 100644 index 0000000..cb33636 --- /dev/null +++ b/test/uscxml/promela/test-event-source-auto.scxml @@ -0,0 +1,45 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/test/uscxml/promela/test-event-source.scxml b/test/uscxml/promela/test-event-source.scxml new file mode 100644 index 0000000..3816bd0 --- /dev/null +++ b/test/uscxml/promela/test-event-source.scxml @@ -0,0 +1,39 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/test/uscxml/promela/test-history.scxml b/test/uscxml/promela/test-history.scxml new file mode 100644 index 0000000..ef48f6a --- /dev/null +++ b/test/uscxml/promela/test-history.scxml @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/test/uscxml/promela/test-ltl.scxml b/test/uscxml/promela/test-ltl.scxml new file mode 100644 index 0000000..23079d9 --- /dev/null +++ b/test/uscxml/promela/test-ltl.scxml @@ -0,0 +1,16 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/test/uscxml/promela/test-non-progress.scxml b/test/uscxml/promela/test-non-progress.scxml new file mode 100644 index 0000000..2301bd6 --- /dev/null +++ b/test/uscxml/promela/test-non-progress.scxml @@ -0,0 +1,17 @@ + + + + + + + + + + \ No newline at end of file diff --git a/test/uscxml/promela/test-progress-label.scxml b/test/uscxml/promela/test-progress-label.scxml new file mode 100644 index 0000000..8e27345 --- /dev/null +++ b/test/uscxml/promela/test-progress-label.scxml @@ -0,0 +1,20 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/test/uscxml/promela/test-simple.scxml b/test/uscxml/promela/test-simple.scxml new file mode 100644 index 0000000..61c8022 --- /dev/null +++ b/test/uscxml/promela/test-simple.scxml @@ -0,0 +1,15 @@ + + + + + + + + + + \ No newline at end of file diff --git a/test/uscxml/promela/test-syntax.scxml b/test/uscxml/promela/test-syntax.scxml new file mode 100644 index 0000000..101c97a --- /dev/null +++ b/test/uscxml/promela/test-syntax.scxml @@ -0,0 +1,132 @@ + + + + + bool b1; + + + int fooSum = 0; + int fooIndex = 0; + int fooItem; + int foos[10]; + + + bool b2, b3, b4; + + + bool b5, b6 = 3 + 4, b7, b8, b9; + + + bool c1; bool c2; bool c3; bool c4; + bool c5; bool c6; bool c7, c8 = 4 + 6, c9; + + + byte state = 1; + mtype = { + FATAL, NON_FATAL, COMPLETE, INCOMPLETE, + red, white, blue + } + + + bool busy[3]; + bool lazy[4]; + + + bool v3, v2 = 1; + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/test/w3c/confPromela.xsl b/test/w3c/confPromela.xsl index a7414b3..37920a5 100644 --- a/test/w3c/confPromela.xsl +++ b/test/w3c/confPromela.xsl @@ -542,7 +542,7 @@ is the second argument --> - _x.states[''] + config[] diff --git a/test/w3c/promela/robots.txt b/test/w3c/promela/robots.txt new file mode 100644 index 0000000..fdd7340 --- /dev/null +++ b/test/w3c/promela/robots.txt @@ -0,0 +1,103 @@ +# +# robots.txt for http://www.w3.org/ +# +# $Id: robots.txt,v 1.74 2016/02/11 20:30:26 gerald 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: /RDF/Validator/rdfval +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: /2012/pyRdfa/extract +Disallow: /WAI/PF/comments/ +Disallow: /participate/conferences.xml +Disallow: /scripts/ +Disallow: /2005/01/yacker/ +Disallow: /2005/01/yacker? +Disallow: /2003/09/nschecker? + 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..3816c3e --- /dev/null +++ b/test/w3c/promela/test150.scxml @@ -0,0 +1,45 @@ + + + + + + + + [1,2,3] + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/test/w3c/promela/test151.scxml b/test/w3c/promela/test151.scxml new file mode 100644 index 0000000..bb50570 --- /dev/null +++ b/test/w3c/promela/test151.scxml @@ -0,0 +1,45 @@ + + + + + + + + [1,2,3] + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/test/w3c/promela/test152.scxml b/test/w3c/promela/test152.scxml new file mode 100644 index 0000000..71f0011 --- /dev/null +++ b/test/w3c/promela/test152.scxml @@ -0,0 +1,51 @@ + + + + + + + + + + [1,2,3] + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/test/w3c/promela/test153.scxml b/test/w3c/promela/test153.scxml new file mode 100644 index 0000000..9890b47 --- /dev/null +++ b/test/w3c/promela/test153.scxml @@ -0,0 +1,42 @@ + + + + + + + + + + [1,2,3] + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/test/w3c/promela/test155.scxml b/test/w3c/promela/test155.scxml new file mode 100644 index 0000000..27fd196 --- /dev/null +++ b/test/w3c/promela/test155.scxml @@ -0,0 +1,31 @@ + + + + + + + + [1,2,3] + + + + + + + + + + + + + + + + + + + + + + diff --git a/test/w3c/promela/test156.scxml b/test/w3c/promela/test156.scxml new file mode 100644 index 0000000..d81a2a2 --- /dev/null +++ b/test/w3c/promela/test156.scxml @@ -0,0 +1,33 @@ + + + + + + + + [1,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..c44a6ab --- /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..0ef8c2e --- /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..b30f6d0 --- /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..fe09a12 --- /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..6fc9a7f --- /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..48a019a --- /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..2d240e7 --- /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..a780b41 --- /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..3fce2d2 --- /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..08612be --- /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..3f139c5 --- /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..8555040 --- /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..e16f838 --- /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..99ee320 --- /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..09bbb25 --- /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..b38d1a2 --- /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..9a003c2 --- /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..137418a --- /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..4030b85 --- /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..e8bd447 --- /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..c54874e --- /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..195d244 --- /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..2e79a98 --- /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..6c6383b --- /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..2a8c76c --- /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..b39e7db --- /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..dc13d5f --- /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..f18b796 --- /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..f2cebaa --- /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..2184c54 --- /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..886f732 --- /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..87d1f0e --- /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..5f5db7f --- /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..383813b --- /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..0747224 --- /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..1cc6010 --- /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..d8777ca --- /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..692b7da --- /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..bde6684 --- /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..2428dcd --- /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..8453a82 --- /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..13a5fbc --- /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..46c702c --- /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..a08590e --- /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..d356f22 --- /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..5e2a5b0 --- /dev/null +++ b/test/w3c/promela/test351.scxml @@ -0,0 +1,47 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/test/w3c/promela/test352.scxml b/test/w3c/promela/test352.scxml new file mode 100644 index 0000000..a113c6a --- /dev/null +++ b/test/w3c/promela/test352.scxml @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/test/w3c/promela/test354.scxml b/test/w3c/promela/test354.scxml new file mode 100644 index 0000000..5a5d234 --- /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..585754d --- /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..481f348 --- /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..9983f48 --- /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..1f9971b --- /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..574d303 --- /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..5de6f9f --- /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..7042e7b --- /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..909d675 --- /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..7b61986 --- /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..b6928b6 --- /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..c4a1421 --- /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..317b8c4 --- /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..564647b --- /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..f4c983d --- /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..ee747f4 --- /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..ed38eea --- /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..12cbf2f --- /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..5527d7f --- /dev/null +++ b/test/w3c/promela/test423.scxml @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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..ea7f1ad --- /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..009a1bc --- /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..11901fa --- /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..0962b3c --- /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..f4c5e39 --- /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..fba68fe --- /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..e98e1c9 --- /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..e2ec38b --- /dev/null +++ b/test/w3c/promela/test525.scxml @@ -0,0 +1,32 @@ + + + + + + [1,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..431802c --- /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..d2ea9a6 --- /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..356342d --- /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..ec9dfc0 --- /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..9ef6405 --- /dev/null +++ b/test/w3c/promela/test551.scxml @@ -0,0 +1,25 @@ + + + + + + + + + + + [1,2,3] + + + + + + + + + + + + + + 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..7f641d4 --- /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..5832090 --- /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..5d99e88 --- /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..1a14640 --- /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..eeff4be --- /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..8ed8ac1 --- /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..f614a12 --- /dev/null +++ b/test/w3c/promela/test580.scxml @@ -0,0 +1,45 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + -- cgit v0.12