diff options
61 files changed, 8274 insertions, 8198 deletions
diff --git a/apps/uscxml-analyze.cpp b/apps/uscxml-analyze.cpp index d9db213..69e403a 100644 --- a/apps/uscxml-analyze.cpp +++ b/apps/uscxml-analyze.cpp @@ -35,18 +35,18 @@ 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(" [-a {ASPECTS}] [-lN]"); + printf("\t%s", progStr.c_str()); + printf(" [-a {ASPECTS}] [-lN]"); #ifdef BUILD_AS_PLUGINS - printf(" [-p pluginPath]"); + printf(" [-p pluginPath]"); #endif - printf(" [URL]"); - printf("\n"); - printf("Options\n"); - printf("\t-a {ASPECTS} : analyze with regard to comma seperated aspects\n"); - printf("\t 'issues' - find common pitfalls and syntactical errors\n"); - printf("\t 'metrics' - print metrics about the state-chart's complexity\n"); - printf("\t-lN : Set loglevel to N\n"); + printf(" [URL]"); + printf("\n"); + printf("Options\n"); + printf("\t-a {ASPECTS} : analyze with regard to comma seperated aspects\n"); + printf("\t 'issues' - find common pitfalls and syntactical errors\n"); + printf("\t 'metrics' - print metrics about the state-chart's complexity\n"); + printf("\t-lN : Set loglevel to N\n"); printf("\n"); exit(1); } @@ -57,7 +57,7 @@ int main(int argc, char** argv) { std::string pluginPath; std::string inputFile; std::list<std::string> aspects; - + #if defined(HAS_SIGNAL_H) && !defined(WIN32) signal(SIGPIPE, SIG_IGN); #endif @@ -72,7 +72,7 @@ int main(int argc, char** argv) { struct option longOptions[] = { {"help", required_argument, 0, 'p'}, {"plugin-path", required_argument, 0, 'p'}, - {"aspect", optional_argument, 0, 'a'}, + {"aspect", optional_argument, 0, 'a'}, {"loglevel", required_argument, 0, 'l'}, {0, 0, 0, 0} }; @@ -94,9 +94,9 @@ int main(int argc, char** argv) { case 'p': pluginPath = optarg; break; - case 'a': - aspects = InterpreterImpl::tokenize(optarg, ','); - break; + case 'a': + aspects = InterpreterImpl::tokenize(optarg, ','); + break; case 'l': break; case 'h': @@ -112,7 +112,7 @@ int main(int argc, char** argv) { if (optind < argc) { inputFile = argv[optind]; } - + // register plugins if (pluginPath.length() > 0) { Factory::setDefaultPluginPath(pluginPath); @@ -142,95 +142,95 @@ int main(int argc, char** argv) { } // analyze here - if (aspects.size() == 0 || std::find(aspects.begin(), aspects.end(), "issues") != aspects.end()) { - std::list<InterpreterIssue> issues = interpreter.validate(); - for (std::list<InterpreterIssue>::iterator issueIter = issues.begin(); issueIter != issues.end(); issueIter++) { - std::cout << *issueIter << std::endl; - } - } - - if (aspects.size() == 0 || std::find(aspects.begin(), aspects.end(), "metrics") != aspects.end()) { - - Arabica::XPath::NodeSet<std::string> states = interpreter.getNodeSetForXPath("//" + interpreter.getNameSpaceInfo().xpathPrefix + "state"); - Arabica::XPath::NodeSet<std::string> final = interpreter.getNodeSetForXPath("//" + interpreter.getNameSpaceInfo().xpathPrefix + "final"); - Arabica::XPath::NodeSet<std::string> parallels = interpreter.getNodeSetForXPath("//" + interpreter.getNameSpaceInfo().xpathPrefix + "parallel"); - Arabica::XPath::NodeSet<std::string> shallowHistories = interpreter.getNodeSetForXPath("//" + interpreter.getNameSpaceInfo().xpathPrefix + "history[@type='shallow']"); - shallowHistories.push_back(interpreter.getNodeSetForXPath("//" + interpreter.getNameSpaceInfo().xpathPrefix + "history[not(@type)]")); - Arabica::XPath::NodeSet<std::string> deepHistories = interpreter.getNodeSetForXPath("//" + interpreter.getNameSpaceInfo().xpathPrefix + "history[@type='deep']"); - Arabica::XPath::NodeSet<std::string> transitions = interpreter.getNodeSetForXPath("//" + interpreter.getNameSpaceInfo().xpathPrefix + "transition"); - - std::cout << "### Number of XML elements" << std::endl; - std::cout << "# <state> + <final> + <parallel> + <history>" << std::endl; - std::cout << "nr_states: " << (states.size() + final.size() + parallels.size() + shallowHistories.size() + deepHistories.size()) << std::endl; - std::cout << "# <parallel>" << std::endl; - std::cout << "nr_parallel: " << parallels.size() << std::endl; - std::cout << "# <history type=\"flat\">" << std::endl; - std::cout << "nr_hist_flat: " << shallowHistories.size() << std::endl; - std::cout << "# <history type=\"deep\">" << std::endl; - std::cout << "nr_hist_deep: " << deepHistories.size() << std::endl; - std::cout << "# <transition>" << std::endl; - std::cout << "nr_trans: " << transitions.size() << std::endl; - std::cout << "#" << std::endl; - - - std::cout << "### Transition Histogram: number of transitions, number of active configurations" << std::endl; - - size_t numberOfLegalConfs = 0; - size_t lastBin = 0; - std::cout << "th: "; - std::string seperator = ""; - std::map<size_t, size_t> histogram = Complexity::getTransitionHistogramm(interpreter.getDocument().getDocumentElement()); - for (std::map<size_t, size_t>::iterator binIter = histogram.begin(); binIter != histogram.end(); binIter++) { - while (binIter->first > lastBin) { - lastBin++; - std::cout << seperator << "0"; - seperator = ", "; - } - std::cout << seperator << binIter->second; - seperator = ", "; - numberOfLegalConfs += binIter->second; - lastBin = binIter->first + 1; - } - std::cout << std::endl << "#" << std::endl; - - - std::stringstream transPowerSetSS; - std::string transPowerSetSeperator = ""; - for (std::map<size_t, size_t>::reverse_iterator binIter = histogram.rbegin(); binIter != histogram.rend(); binIter++) { - transPowerSetSS << transPowerSetSeperator << binIter->second << " * " << "2**" << binIter->first; - transPowerSetSeperator = " + "; - } - std::cout << "# Sum of Powersets:" << std::endl; - std::cout << "ps_sum: " << transPowerSetSS.str() << std::endl; - std::cout << "#" << std::endl; - - std::cout << "### Upper bounds:" << std::endl; - std::cout << "# \tActive configurations: " << std::endl; - std::cout << "up_ac: " << numberOfLegalConfs << std::endl; - std::cout << "# \tGlobal configurations: " << std::endl; - std::cout << "up_gc: " << Complexity::stateMachineComplexity(interpreter) << std::endl; - - std::cout << "# \tGlobal configurations (no history): " << std::endl; - std::cout << "up_gcnh: " << Complexity::stateMachineComplexity(interpreter, uscxml::Complexity::IGNORE_HISTORY) << std::endl; - - std::cout << "# \tGlobal configurations (no nested data): " << std::endl; - std::cout << "up_gcnd: " << Complexity::stateMachineComplexity(interpreter, uscxml::Complexity::IGNORE_NESTED_DATA) << std::endl; - - std::cout << "# \tGlobal configurations (no unreachable): " << std::endl; - std::cout << "up_gcnu: " << Complexity::stateMachineComplexity(interpreter, uscxml::Complexity::IGNORE_UNREACHABLE) << std::endl; - - std::cout << "# \tGlobal configurations (no nested data, no history): " << std::endl; - std::cout << "up_gcnhd: " << Complexity::stateMachineComplexity(interpreter, uscxml::Complexity::IGNORE_HISTORY | uscxml::Complexity::IGNORE_NESTED_DATA) << std::endl; - - std::cout << "# \tGlobal configurations (no history, no unreachable): " << std::endl; - std::cout << "up_gcnhu: " << Complexity::stateMachineComplexity(interpreter, uscxml::Complexity::IGNORE_HISTORY | uscxml::Complexity::IGNORE_UNREACHABLE) << std::endl; - - std::cout << "# \tGlobal configurations (no nested data, no unreachable): " << std::endl; - std::cout << "up_gcndu: " << Complexity::stateMachineComplexity(interpreter, uscxml::Complexity::IGNORE_NESTED_DATA | uscxml::Complexity::IGNORE_UNREACHABLE) << std::endl; - - std::cout << "# \tGlobal configurations (no nested data, no history, no unreachable): " << std::endl; - std::cout << "up_gcnhdu: " << Complexity::stateMachineComplexity(interpreter, uscxml::Complexity::IGNORE_HISTORY | uscxml::Complexity::IGNORE_NESTED_DATA | uscxml::Complexity::IGNORE_UNREACHABLE) << std::endl; - } + if (aspects.size() == 0 || std::find(aspects.begin(), aspects.end(), "issues") != aspects.end()) { + std::list<InterpreterIssue> issues = interpreter.validate(); + for (std::list<InterpreterIssue>::iterator issueIter = issues.begin(); issueIter != issues.end(); issueIter++) { + std::cout << *issueIter << std::endl; + } + } + + if (aspects.size() == 0 || std::find(aspects.begin(), aspects.end(), "metrics") != aspects.end()) { + + Arabica::XPath::NodeSet<std::string> states = interpreter.getNodeSetForXPath("//" + interpreter.getNameSpaceInfo().xpathPrefix + "state"); + Arabica::XPath::NodeSet<std::string> final = interpreter.getNodeSetForXPath("//" + interpreter.getNameSpaceInfo().xpathPrefix + "final"); + Arabica::XPath::NodeSet<std::string> parallels = interpreter.getNodeSetForXPath("//" + interpreter.getNameSpaceInfo().xpathPrefix + "parallel"); + Arabica::XPath::NodeSet<std::string> shallowHistories = interpreter.getNodeSetForXPath("//" + interpreter.getNameSpaceInfo().xpathPrefix + "history[@type='shallow']"); + shallowHistories.push_back(interpreter.getNodeSetForXPath("//" + interpreter.getNameSpaceInfo().xpathPrefix + "history[not(@type)]")); + Arabica::XPath::NodeSet<std::string> deepHistories = interpreter.getNodeSetForXPath("//" + interpreter.getNameSpaceInfo().xpathPrefix + "history[@type='deep']"); + Arabica::XPath::NodeSet<std::string> transitions = interpreter.getNodeSetForXPath("//" + interpreter.getNameSpaceInfo().xpathPrefix + "transition"); + + std::cout << "### Number of XML elements" << std::endl; + std::cout << "# <state> + <final> + <parallel> + <history>" << std::endl; + std::cout << "nr_states: " << (states.size() + final.size() + parallels.size() + shallowHistories.size() + deepHistories.size()) << std::endl; + std::cout << "# <parallel>" << std::endl; + std::cout << "nr_parallel: " << parallels.size() << std::endl; + std::cout << "# <history type=\"flat\">" << std::endl; + std::cout << "nr_hist_flat: " << shallowHistories.size() << std::endl; + std::cout << "# <history type=\"deep\">" << std::endl; + std::cout << "nr_hist_deep: " << deepHistories.size() << std::endl; + std::cout << "# <transition>" << std::endl; + std::cout << "nr_trans: " << transitions.size() << std::endl; + std::cout << "#" << std::endl; + + + std::cout << "### Transition Histogram: number of transitions, number of active configurations" << std::endl; + + size_t numberOfLegalConfs = 0; + size_t lastBin = 0; + std::cout << "th: "; + std::string seperator = ""; + std::map<size_t, size_t> histogram = Complexity::getTransitionHistogramm(interpreter.getDocument().getDocumentElement()); + for (std::map<size_t, size_t>::iterator binIter = histogram.begin(); binIter != histogram.end(); binIter++) { + while (binIter->first > lastBin) { + lastBin++; + std::cout << seperator << "0"; + seperator = ", "; + } + std::cout << seperator << binIter->second; + seperator = ", "; + numberOfLegalConfs += binIter->second; + lastBin = binIter->first + 1; + } + std::cout << std::endl << "#" << std::endl; + + + std::stringstream transPowerSetSS; + std::string transPowerSetSeperator = ""; + for (std::map<size_t, size_t>::reverse_iterator binIter = histogram.rbegin(); binIter != histogram.rend(); binIter++) { + transPowerSetSS << transPowerSetSeperator << binIter->second << " * " << "2**" << binIter->first; + transPowerSetSeperator = " + "; + } + std::cout << "# Sum of Powersets:" << std::endl; + std::cout << "ps_sum: " << transPowerSetSS.str() << std::endl; + std::cout << "#" << std::endl; + + std::cout << "### Upper bounds:" << std::endl; + std::cout << "# \tActive configurations: " << std::endl; + std::cout << "up_ac: " << numberOfLegalConfs << std::endl; + std::cout << "# \tGlobal configurations: " << std::endl; + std::cout << "up_gc: " << Complexity::stateMachineComplexity(interpreter) << std::endl; + + std::cout << "# \tGlobal configurations (no history): " << std::endl; + std::cout << "up_gcnh: " << Complexity::stateMachineComplexity(interpreter, uscxml::Complexity::IGNORE_HISTORY) << std::endl; + + std::cout << "# \tGlobal configurations (no nested data): " << std::endl; + std::cout << "up_gcnd: " << Complexity::stateMachineComplexity(interpreter, uscxml::Complexity::IGNORE_NESTED_DATA) << std::endl; + + std::cout << "# \tGlobal configurations (no unreachable): " << std::endl; + std::cout << "up_gcnu: " << Complexity::stateMachineComplexity(interpreter, uscxml::Complexity::IGNORE_UNREACHABLE) << std::endl; + + std::cout << "# \tGlobal configurations (no nested data, no history): " << std::endl; + std::cout << "up_gcnhd: " << Complexity::stateMachineComplexity(interpreter, uscxml::Complexity::IGNORE_HISTORY | uscxml::Complexity::IGNORE_NESTED_DATA) << std::endl; + + std::cout << "# \tGlobal configurations (no history, no unreachable): " << std::endl; + std::cout << "up_gcnhu: " << Complexity::stateMachineComplexity(interpreter, uscxml::Complexity::IGNORE_HISTORY | uscxml::Complexity::IGNORE_UNREACHABLE) << std::endl; + + std::cout << "# \tGlobal configurations (no nested data, no unreachable): " << std::endl; + std::cout << "up_gcndu: " << Complexity::stateMachineComplexity(interpreter, uscxml::Complexity::IGNORE_NESTED_DATA | uscxml::Complexity::IGNORE_UNREACHABLE) << std::endl; + + std::cout << "# \tGlobal configurations (no nested data, no history, no unreachable): " << std::endl; + std::cout << "up_gcnhdu: " << Complexity::stateMachineComplexity(interpreter, uscxml::Complexity::IGNORE_HISTORY | uscxml::Complexity::IGNORE_NESTED_DATA | uscxml::Complexity::IGNORE_UNREACHABLE) << std::endl; + } } catch (Event e) { std::cout << e << std::endl; } diff --git a/apps/uscxml-browser.cpp b/apps/uscxml-browser.cpp index ede6f06..10f52cc 100644 --- a/apps/uscxml-browser.cpp +++ b/apps/uscxml-browser.cpp @@ -139,7 +139,7 @@ int main(int argc, char** argv) { DebuggerServlet* debugger; if (options.withDebugger) { debugger = new DebuggerServlet(); - debugger->copyToInvokers(true); + debugger->copyToInvokers(true); HTTPServer::getInstance()->registerServlet("/debug", debugger); } #endif @@ -171,7 +171,7 @@ int main(int argc, char** argv) { if (options.verbose) { StateTransitionMonitor* vm = new StateTransitionMonitor(); - vm->copyToInvokers(true); + vm->copyToInvokers(true); interpreter.addMonitor(vm); } diff --git a/apps/uscxml-transform.cpp b/apps/uscxml-transform.cpp index 95bb60b..64d6b06 100644 --- a/apps/uscxml-transform.cpp +++ b/apps/uscxml-transform.cpp @@ -70,24 +70,24 @@ void printUsageAndExit(const char* progName) { printf(" [-i URL] [-o FILE]"); printf("\n"); printf("Options\n"); - printf("\t-t c : convert to C program\n"); - printf("\t-t pml : convert to spin/promela program\n"); - printf("\t-t flat : flatten to SCXML state-machine\n"); + printf("\t-t c : convert to C program\n"); + printf("\t-t pml : convert to spin/promela program\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"); - printf("\t 'entryset' - annotate all transitions with their entry sets\n"); - printf("\t 'conflicts' - annotate all transitions with their conflicts\n"); - printf("\t 'domain' - annotate all transitions with their domain\n"); + printf("\t 'exitset' - annotate all transitions with their exit sets\n"); + printf("\t 'entryset' - annotate all transitions with their entry sets\n"); + printf("\t 'conflicts' - annotate all transitions with their conflicts\n"); + printf("\t 'domain' - annotate all transitions with their domain\n"); printf("\t 'step' - global states with their step identifier (-tflat only)\n"); printf("\t 'members' - global transitions with their member transitions per index (-tflat only)\n"); printf("\t 'sends' - transititve number of sends to external queue for global transitions (-tflat only)\n"); printf("\t 'raises' - transititve number of raises to internal queue for global transitions (-tflat only)\n"); - printf("\t 'verbose' - comments detailling state changes and transitions for content selection (-tflat only)\n"); - printf("\t 'progress' - insert comments documenting progress in dociment (-tmin only)\n"); - printf("\t 'nocomment' - surpress the generation of comments in output\n"); + printf("\t 'verbose' - comments detailling state changes and transitions for content selection (-tflat only)\n"); + printf("\t 'progress' - insert comments documenting progress in dociment (-tmin only)\n"); + printf("\t 'nocomment' - surpress the generation of comments in output\n"); printf("\t-v : be verbose\n"); printf("\t-lN : Set loglevel to N\n"); printf("\t-i URL : Input file (defaults to STDIN)\n"); @@ -105,7 +105,7 @@ int main(int argc, char** argv) { std::string inputFile; std::string outputFile; std::list<std::string> annotations; - + #if defined(HAS_SIGNAL_H) && !defined(WIN32) signal(SIGPIPE, SIG_IGN); #endif @@ -180,17 +180,17 @@ int main(int argc, char** argv) { if (ANNOTATE("USCXML_ANNOTATE_VERBOSE_COMMENTS", "verbose")) setenv("USCXML_ANNOTATE_VERBOSE_COMMENTS", "YES", 1); - if (ANNOTATE("USCXML_ANNOTATE_TRANS_EXITSET", "exitset")) - setenv("USCXML_ANNOTATE_TRANS_EXITSET", "YES", 1); + if (ANNOTATE("USCXML_ANNOTATE_TRANS_EXITSET", "exitset")) + setenv("USCXML_ANNOTATE_TRANS_EXITSET", "YES", 1); - if (ANNOTATE("USCXML_ANNOTATE_TRANS_DOMAIN", "domain")) - setenv("USCXML_ANNOTATE_TRANS_DOMAIN", "YES", 1); + if (ANNOTATE("USCXML_ANNOTATE_TRANS_DOMAIN", "domain")) + setenv("USCXML_ANNOTATE_TRANS_DOMAIN", "YES", 1); - if (ANNOTATE("USCXML_ANNOTATE_TRANS_CONFLICTS", "conflicts")) - setenv("USCXML_ANNOTATE_TRANS_CONFLICTS", "YES", 1); + if (ANNOTATE("USCXML_ANNOTATE_TRANS_CONFLICTS", "conflicts")) + setenv("USCXML_ANNOTATE_TRANS_CONFLICTS", "YES", 1); - if (ANNOTATE("USCXML_ANNOTATE_TRANS_ENTRYSET", "entryset")) - setenv("USCXML_ANNOTATE_TRANS_ENTRYSET", "YES", 1); + if (ANNOTATE("USCXML_ANNOTATE_TRANS_ENTRYSET", "entryset")) + setenv("USCXML_ANNOTATE_TRANS_ENTRYSET", "YES", 1); if(ANNOTATE("USCXML_ANNOTATE_GLOBAL_TRANS_MEMBERS", "members")) setenv("USCXML_ANNOTATE_GLOBAL_TRANS_MEMBERS", "YES", 1); @@ -204,10 +204,10 @@ int main(int argc, char** argv) { if(ANNOTATE("USCXML_ANNOTATE_PROGRESS", "progress")) setenv("USCXML_ANNOTATE_PROGRESS", "YES", 1); - if(ANNOTATE("USCXML_ANNOTATE_NOCOMMENT", "nocomment")) - setenv("USCXML_ANNOTATE_NOCOMMENT", "YES", 1); + if(ANNOTATE("USCXML_ANNOTATE_NOCOMMENT", "nocomment")) + setenv("USCXML_ANNOTATE_NOCOMMENT", "YES", 1); + - // if (outType.length() == 0 && outputFile.length() > 0) { // // try to get type from outfile extension // size_t dotPos = outputFile.find_last_of("."); @@ -215,21 +215,21 @@ int main(int argc, char** argv) { // outType= outputFile.substr(dotPos + 1); // } // } - + // if (outType.length() == 0) // printUsageAndExit(argv[0]); if (outType != "flat" && - outType != "scxml" && - outType != "pml" && - outType != "c" && - outType != "min" && - outType != "tex" && - std::find(annotations.begin(), annotations.end(), "priority") == annotations.end() && - std::find(annotations.begin(), annotations.end(), "domain") == annotations.end() && - std::find(annotations.begin(), annotations.end(), "conflicts") == annotations.end() && - std::find(annotations.begin(), annotations.end(), "exitset") == annotations.end() && - std::find(annotations.begin(), annotations.end(), "entryset") == annotations.end()) + outType != "scxml" && + outType != "pml" && + outType != "c" && + outType != "min" && + outType != "tex" && + std::find(annotations.begin(), annotations.end(), "priority") == annotations.end() && + std::find(annotations.begin(), annotations.end(), "domain") == annotations.end() && + std::find(annotations.begin(), annotations.end(), "conflicts") == annotations.end() && + std::find(annotations.begin(), annotations.end(), "exitset") == annotations.end() && + std::find(annotations.begin(), annotations.end(), "entryset") == annotations.end()) printUsageAndExit(argv[0]); // register plugins @@ -266,18 +266,18 @@ int main(int argc, char** argv) { std::cerr << *issueIter << std::endl; } } - - if (outType == "c") { - if (outputFile.size() == 0 || outputFile == "-") { - ChartToC::transform(interpreter).writeTo(std::cout); - } else { - std::ofstream outStream; - outStream.open(outputFile.c_str()); - ChartToC::transform(interpreter).writeTo(outStream); - outStream.close(); - } - exit(EXIT_SUCCESS); - } + + if (outType == "c") { + if (outputFile.size() == 0 || outputFile == "-") { + ChartToC::transform(interpreter).writeTo(std::cout); + } else { + std::ofstream outStream; + outStream.open(outputFile.c_str()); + ChartToC::transform(interpreter).writeTo(outStream); + outStream.close(); + } + exit(EXIT_SUCCESS); + } if (outType == "pml") { if (outputFile.size() == 0 || outputFile == "-") { @@ -327,34 +327,34 @@ int main(int argc, char** argv) { exit(EXIT_SUCCESS); } - + #if 1 - if (annotations.size() > 0) { - ChartToFSM annotater(interpreter); - if (std::find(annotations.begin(), annotations.end(), "priority") != annotations.end()) - annotater.indexTransitions(); - if (std::find(annotations.begin(), annotations.end(), "conflicts") != annotations.end()) - annotater.annotateConflicts(); - if (std::find(annotations.begin(), annotations.end(), "exitset") != annotations.end()) - annotater.annotateExitSet(); - if (std::find(annotations.begin(), annotations.end(), "entryset") != annotations.end()) - annotater.annotateEntrySet(); - if (std::find(annotations.begin(), annotations.end(), "domain") != annotations.end()) - annotater.annotateDomain(); - - if (outputFile.size() == 0 || outputFile == "-") { - std::cout << annotater.getDocument(); - } else { - std::ofstream outStream; - outStream.open(outputFile.c_str()); - outStream << annotater.getDocument(); - outStream.close(); - } - exit(EXIT_SUCCESS); - } + if (annotations.size() > 0) { + ChartToFSM annotater(interpreter); + if (std::find(annotations.begin(), annotations.end(), "priority") != annotations.end()) + annotater.indexTransitions(); + if (std::find(annotations.begin(), annotations.end(), "conflicts") != annotations.end()) + annotater.annotateConflicts(); + if (std::find(annotations.begin(), annotations.end(), "exitset") != annotations.end()) + annotater.annotateExitSet(); + if (std::find(annotations.begin(), annotations.end(), "entryset") != annotations.end()) + annotater.annotateEntrySet(); + if (std::find(annotations.begin(), annotations.end(), "domain") != annotations.end()) + annotater.annotateDomain(); + + if (outputFile.size() == 0 || outputFile == "-") { + std::cout << annotater.getDocument(); + } else { + std::ofstream outStream; + outStream.open(outputFile.c_str()); + outStream << annotater.getDocument(); + outStream.close(); + } + exit(EXIT_SUCCESS); + } #endif - + } catch (Event e) { std::cout << e << std::endl; } diff --git a/src/bindings/swig/wrapped/WrappedDataModel.h b/src/bindings/swig/wrapped/WrappedDataModel.h index 6927045..efb4ef1 100644 --- a/src/bindings/swig/wrapped/WrappedDataModel.h +++ b/src/bindings/swig/wrapped/WrappedDataModel.h @@ -37,14 +37,18 @@ class WrappedDataModelExtension : public DataModelExtension { public: WrappedDataModelExtension(); virtual ~WrappedDataModelExtension(); - virtual std::string provides() { return ""; } - virtual Data getValueOf(const std::string& member) { return Data(); } + virtual std::string provides() { + return ""; + } + virtual Data getValueOf(const std::string& member) { + return Data(); + } virtual void setValueOf(const std::string& member, const Data& data) { } }; class WrappedDataModel : public DataModelImpl { public: - + WrappedDataModel(); virtual ~WrappedDataModel(); @@ -55,7 +59,7 @@ public: virtual boost::shared_ptr<DataModelImpl> create(InterpreterInfo* interpreter) { return boost::shared_ptr<DataModelImpl>(create(_interpreter)); } - + virtual boost::shared_ptr<DataModelImpl> create(InterpreterImpl* interpreter) { _interpreter = interpreter->shared_from_this(); return boost::shared_ptr<DataModelImpl>(create(_interpreter)); diff --git a/src/uscxml/Common.h b/src/uscxml/Common.h index 85729f2..9d35222 100644 --- a/src/uscxml/Common.h +++ b/src/uscxml/Common.h @@ -53,15 +53,14 @@ #endif #if defined(_WIN32) -inline int setenv(const char *name, const char *value, int overwrite) -{ - int errcode = 0; - if(!overwrite) { - size_t envsize = 0; - errcode = getenv_s(&envsize, NULL, 0, name); - if(errcode || envsize) return errcode; - } - return _putenv_s(name, value); +inline int setenv(const char *name, const char *value, int overwrite) { + int errcode = 0; + if(!overwrite) { + size_t envsize = 0; + errcode = getenv_s(&envsize, NULL, 0, name); + if(errcode || envsize) return errcode; + } + return _putenv_s(name, value); } #endif diff --git a/src/uscxml/Convenience.cpp b/src/uscxml/Convenience.cpp index 5d81db7..6534636 100644 --- a/src/uscxml/Convenience.cpp +++ b/src/uscxml/Convenience.cpp @@ -26,7 +26,7 @@ namespace uscxml { bool isnan(double x) { return x != x; } - + bool isNumeric(const char* pszInput, int nNumberBase) { std::string base = ".-0123456789ABCDEF"; std::string input = pszInput; @@ -62,9 +62,9 @@ bool equals(const std::string& a, const std::string& b) { bool stringIsTrue(const std::string& value) { return (iequals(value, "on") || - iequals(value, "true") || - iequals(value, "1") || - iequals(value, "yes")); + iequals(value, "true") || + iequals(value, "1") || + iequals(value, "yes")); } bool envVarIsTrue(const char* name) { @@ -88,90 +88,90 @@ std::string escape(const std::string& a) { std::string::const_iterator it = a.begin(); while (it != a.end()) { char c = *it++; - switch (c) { - case '\\': - b << '\\' << '\\'; - break; - case '\0': - b << '\\' << '0'; - break; - case '"': - b << '\\' << '"'; - break; - case '\a': - b << '\\' << 'a'; - break; - case '\b': - b << '\\' << 'b'; - break; - case '\f': - b << '\\' << 'f'; - break; - case '\n': - b << '\\' << 'n'; - break; - case '\r': - b << '\\' << 'r'; - break; - case '\t': - b << '\\' << 't'; - break; - case '\v': - b << '\\' << 'v'; - break; - default: - b << c; - } + switch (c) { + case '\\': + b << '\\' << '\\'; + break; + case '\0': + b << '\\' << '0'; + break; + case '"': + b << '\\' << '"'; + break; + case '\a': + b << '\\' << 'a'; + break; + case '\b': + b << '\\' << 'b'; + break; + case '\f': + b << '\\' << 'f'; + break; + case '\n': + b << '\\' << 'n'; + break; + case '\r': + b << '\\' << 'r'; + break; + case '\t': + b << '\\' << 't'; + break; + case '\v': + b << '\\' << 'v'; + break; + default: + b << c; + } } return b.str(); } std::string unescape(const std::string& a) { - std::stringstream b; - // see http://en.cppreference.com/w/cpp/language/escape - - std::string::const_iterator it = a.begin(); - while (it != a.end()) { - char c = *it++; - if (c == '\\' && it != a.end()) { - switch (*it++) { - case '\\': - c = '\\'; - break; - case '0': - c = '\0'; - break; - case '"': - c = '"'; - break; - case 'a': - c = '\a'; - break; - case 'b': - c = '\b'; - break; - case 'f': - c = '\f'; - break; - case 'n': - c = '\n'; - break; - case 'r': - c = '\r'; - break; - case 't': - c = '\t'; - break; - case 'v': - c = '\v'; - break; - } - } - b << c; - } - - return b.str(); + std::stringstream b; + // see http://en.cppreference.com/w/cpp/language/escape + + std::string::const_iterator it = a.begin(); + while (it != a.end()) { + char c = *it++; + if (c == '\\' && it != a.end()) { + switch (*it++) { + case '\\': + c = '\\'; + break; + case '0': + c = '\0'; + break; + case '"': + c = '"'; + break; + case 'a': + c = '\a'; + break; + case 'b': + c = '\b'; + break; + case 'f': + c = '\f'; + break; + case 'n': + c = '\n'; + break; + case 'r': + c = '\r'; + break; + case 't': + c = '\t'; + break; + case 'v': + c = '\v'; + break; + } + } + b << c; + } + + return b.str(); } } diff --git a/src/uscxml/Convenience.h b/src/uscxml/Convenience.h index 88afa8d..d715d3e 100644 --- a/src/uscxml/Convenience.h +++ b/src/uscxml/Convenience.h @@ -28,7 +28,7 @@ namespace uscxml { inline bool isnan(double x); - + // see http://stackoverflow.com/questions/228005/alternative-to-itoa-for-converting-integer-to-string-c template <typename T> std::string toStr(T tmp) { std::ostringstream out; @@ -46,27 +46,27 @@ template <typename T> T strTo(std::string tmp) { class USCXML_API NumAttr { public: - NumAttr(const std::string& str) { - size_t valueStart = str.find_first_of("0123456789."); - if (valueStart != std::string::npos) { - size_t valueEnd = str.find_last_of("0123456789."); - if (valueEnd != std::string::npos) { - value = str.substr(valueStart, (valueEnd - valueStart) + 1); - size_t unitStart = str.find_first_not_of(" \t", valueEnd + 1); - if (unitStart != std::string::npos) { - size_t unitEnd = str.find_last_of(" \t"); - if (unitEnd != std::string::npos && unitEnd > unitStart) { - unit = str.substr(unitStart, unitEnd - unitStart); - } else { - unit = str.substr(unitStart, str.length() - unitStart); - } - } - } - } - } - - std::string value; - std::string unit; + NumAttr(const std::string& str) { + size_t valueStart = str.find_first_of("0123456789."); + if (valueStart != std::string::npos) { + size_t valueEnd = str.find_last_of("0123456789."); + if (valueEnd != std::string::npos) { + value = str.substr(valueStart, (valueEnd - valueStart) + 1); + size_t unitStart = str.find_first_not_of(" \t", valueEnd + 1); + if (unitStart != std::string::npos) { + size_t unitEnd = str.find_last_of(" \t"); + if (unitEnd != std::string::npos && unitEnd > unitStart) { + unit = str.substr(unitStart, unitEnd - unitStart); + } else { + unit = str.substr(unitStart, str.length() - unitStart); + } + } + } + } + } + + std::string value; + std::string unit; }; bool isNumeric(const char* pszInput, int nNumberBase); diff --git a/src/uscxml/DOMUtils.cpp b/src/uscxml/DOMUtils.cpp index 4805927..7e834f8 100644 --- a/src/uscxml/DOMUtils.cpp +++ b/src/uscxml/DOMUtils.cpp @@ -31,40 +31,40 @@ bool DOMUtils::attributeIsTrue(const::std::string& value) { } std::string DOMUtils::idForNode(const Arabica::DOM::Node<std::string>& node) { - std::string nodeId; - std::string seperator; - Arabica::DOM::Node<std::string> curr = node; - while(curr) { - switch (curr.getNodeType()) { - case Arabica::DOM::Node_base::ELEMENT_NODE: { - Arabica::DOM::Element<std::string> elem = Arabica::DOM::Element<std::string>(curr); - if (HAS_ATTR(elem, "id") && !UUID::isUUID(ATTR(elem, "id"))) { - nodeId.insert(0, ATTR(elem, "id") + seperator); - seperator = "_"; - return nodeId; - } else { - Arabica::DOM::Node<std::string> sibling = curr.getPreviousSibling(); - int index = 0; - while(sibling) { - if (sibling.getNodeType() == Arabica::DOM::Node_base::ELEMENT_NODE) { - if (iequals(TAGNAME_CAST(sibling), TAGNAME(elem))) { - index++; - } - } - sibling = sibling.getPreviousSibling(); - } - nodeId.insert(0, TAGNAME(elem) + toStr(index) + seperator); - seperator = "_"; - } - break; - } - case Arabica::DOM::Node_base::DOCUMENT_NODE: - return nodeId; - } - - curr = curr.getParentNode(); - } - return nodeId; + std::string nodeId; + std::string seperator; + Arabica::DOM::Node<std::string> curr = node; + while(curr) { + switch (curr.getNodeType()) { + case Arabica::DOM::Node_base::ELEMENT_NODE: { + Arabica::DOM::Element<std::string> elem = Arabica::DOM::Element<std::string>(curr); + if (HAS_ATTR(elem, "id") && !UUID::isUUID(ATTR(elem, "id"))) { + nodeId.insert(0, ATTR(elem, "id") + seperator); + seperator = "_"; + return nodeId; + } else { + Arabica::DOM::Node<std::string> sibling = curr.getPreviousSibling(); + int index = 0; + while(sibling) { + if (sibling.getNodeType() == Arabica::DOM::Node_base::ELEMENT_NODE) { + if (iequals(TAGNAME_CAST(sibling), TAGNAME(elem))) { + index++; + } + } + sibling = sibling.getPreviousSibling(); + } + nodeId.insert(0, TAGNAME(elem) + toStr(index) + seperator); + seperator = "_"; + } + break; + } + case Arabica::DOM::Node_base::DOCUMENT_NODE: + return nodeId; + } + + curr = curr.getParentNode(); + } + return nodeId; } std::string DOMUtils::xPathForNode(const Arabica::DOM::Node<std::string>& node, const std::string& ns) { @@ -164,7 +164,7 @@ NameSpacingParser NameSpacingParser::fromFile(const std::string& file) { inputSource.setSystemId(file); return fromInputSource(inputSource); } - + NameSpacingParser NameSpacingParser::fromXML(const std::string& xml) { std::stringstream* ss = new std::stringstream(); (*ss) << xml; diff --git a/src/uscxml/DOMUtils.h b/src/uscxml/DOMUtils.h index fcd80d9..426d797 100644 --- a/src/uscxml/DOMUtils.h +++ b/src/uscxml/DOMUtils.h @@ -44,8 +44,8 @@ class USCXML_API DOMUtils { public: static std::string xPathForNode(const Arabica::DOM::Node<std::string>& node, const std::string& ns = ""); static std::list<Arabica::DOM::Node<std::string> > getElementsByType(const Arabica::DOM::Node<std::string>& root, Arabica::DOM::Node_base::Type type); - static std::string idForNode(const Arabica::DOM::Node<std::string>& node); - // deprecated, use stringIsTrue from Convenience.h instead + static std::string idForNode(const Arabica::DOM::Node<std::string>& node); + // deprecated, use stringIsTrue from Convenience.h instead DEPRECATED static bool attributeIsTrue(const::std::string& value); }; diff --git a/src/uscxml/Interpreter.cpp b/src/uscxml/Interpreter.cpp index 4e45599..2a15924 100644 --- a/src/uscxml/Interpreter.cpp +++ b/src/uscxml/Interpreter.cpp @@ -330,39 +330,39 @@ void NameSpaceInfo::init(const std::map<std::string, std::string>& namespaceInfo } void StateTransitionMonitor::beforeTakingTransition(uscxml::Interpreter interpreter, const Arabica::DOM::Element<std::string>& transition, bool moreComing) { - tthread::lock_guard<tthread::recursive_mutex> lock(_mutex); + tthread::lock_guard<tthread::recursive_mutex> lock(_mutex); std::cerr << "Transition: " << uscxml::DOMUtils::xPathForNode(transition) << std::endl; } void StateTransitionMonitor::onStableConfiguration(uscxml::Interpreter interpreter) { - tthread::lock_guard<tthread::recursive_mutex> lock(_mutex); + tthread::lock_guard<tthread::recursive_mutex> lock(_mutex); std::cerr << "Config: {"; printNodeSet(interpreter.getConfiguration()); std::cerr << "}" << std::endl; } void StateTransitionMonitor::beforeProcessingEvent(uscxml::Interpreter interpreter, const uscxml::Event& event) { - tthread::lock_guard<tthread::recursive_mutex> lock(_mutex); + tthread::lock_guard<tthread::recursive_mutex> lock(_mutex); switch (event.eventType) { - case uscxml::Event::INTERNAL: - std::cerr << "Internal Event: " << event.name << std::endl; - break; - case uscxml::Event::EXTERNAL: - std::cerr << "External Event: " << event.name << std::endl; - break; - case uscxml::Event::PLATFORM: - std::cerr << "Platform Event: " << event.name << std::endl; - break; + case uscxml::Event::INTERNAL: + std::cerr << "Internal Event: " << event.name << std::endl; + break; + case uscxml::Event::EXTERNAL: + std::cerr << "External Event: " << event.name << std::endl; + break; + case uscxml::Event::PLATFORM: + std::cerr << "Platform Event: " << event.name << std::endl; + break; } } void StateTransitionMonitor::beforeExecutingContent(Interpreter interpreter, const Arabica::DOM::Element<std::string>& element) { - tthread::lock_guard<tthread::recursive_mutex> lock(_mutex); + tthread::lock_guard<tthread::recursive_mutex> lock(_mutex); std::cerr << "Executable Content: " << DOMUtils::xPathForNode(element) << std::endl; } void StateTransitionMonitor::beforeExitingState(uscxml::Interpreter interpreter, const Arabica::DOM::Element<std::string>& state, bool moreComing) { - tthread::lock_guard<tthread::recursive_mutex> lock(_mutex); + tthread::lock_guard<tthread::recursive_mutex> lock(_mutex); exitingStates.push_back(state); if (!moreComing) { std::cerr << "Exiting: {"; @@ -373,7 +373,7 @@ void StateTransitionMonitor::beforeExitingState(uscxml::Interpreter interpreter, } void StateTransitionMonitor::beforeEnteringState(uscxml::Interpreter interpreter, const Arabica::DOM::Element<std::string>& state, bool moreComing) { - tthread::lock_guard<tthread::recursive_mutex> lock(_mutex); + tthread::lock_guard<tthread::recursive_mutex> lock(_mutex); enteringStates.push_back(state); if (!moreComing) { std::cerr << "Entering: {"; @@ -381,7 +381,7 @@ void StateTransitionMonitor::beforeEnteringState(uscxml::Interpreter interpreter std::cerr << "}" << std::endl; enteringStates = Arabica::XPath::NodeSet<std::string>(); } - + } void StateTransitionMonitor::printNodeSet(const Arabica::XPath::NodeSet<std::string>& config) { @@ -392,7 +392,7 @@ void StateTransitionMonitor::printNodeSet(const Arabica::XPath::NodeSet<std::str } } tthread::recursive_mutex StateTransitionMonitor::_mutex; - + std::map<std::string, boost::weak_ptr<InterpreterImpl> > Interpreter::_instances; tthread::recursive_mutex Interpreter::_instanceMutex; @@ -572,7 +572,7 @@ void InterpreterImpl::cloneFrom(InterpreterImpl* other) { } setNameSpaceInfo(other->_nsInfo); - + _baseURL = other->_baseURL; _sourceURL = other->_sourceURL; @@ -772,7 +772,7 @@ NodeSet<std::string> InterpreterImpl::getDocumentInitialTransitions() { } InterpreterState InterpreterImpl::step(int waitForMS) { - try { + try { tthread::lock_guard<tthread::recursive_mutex> lock(_mutex); if (_state == USCXML_FINISHED || _state == USCXML_DESTROYED) { @@ -798,13 +798,13 @@ InterpreterState InterpreterImpl::step(int waitForMS) { std::cerr << std::endl; #endif - // this is not mentionend in the standard, though it makes sense - for (int i = 0; i < initialTransitions.size(); i++) { - Element<std::string> transition(initialTransitions[i]); - USCXML_MONITOR_CALLBACK3(beforeTakingTransition, transition, (i + 1 < enabledTransitions.size())) - executeContent(transition); - USCXML_MONITOR_CALLBACK3(afterTakingTransition, transition, (i + 1 < enabledTransitions.size())) - } + // this is not mentionend in the standard, though it makes sense + for (int i = 0; i < initialTransitions.size(); i++) { + Element<std::string> transition(initialTransitions[i]); + USCXML_MONITOR_CALLBACK3(beforeTakingTransition, transition, (i + 1 < enabledTransitions.size())) + executeContent(transition); + USCXML_MONITOR_CALLBACK3(afterTakingTransition, transition, (i + 1 < enabledTransitions.size())) + } enterStates(initialTransitions); setInterpreterState(USCXML_MICROSTEPPED); @@ -1066,7 +1066,7 @@ void InterpreterImpl::stabilize() { } #if 0 - + Arabica::XPath::NodeSet<std::string> InterpreterImpl::selectTransitions(const std::string& event) { Arabica::XPath::NodeSet<std::string> enabledTransitions; @@ -1148,100 +1148,102 @@ LOOP: #else Arabica::XPath::NodeSet<std::string> InterpreterImpl::selectTransitions(const std::string& event) { - Arabica::XPath::NodeSet<std::string> enabledTransitions; - - NodeSet<std::string> atomicStates; - for (unsigned int i = 0; i < _configuration.size(); i++) { - if (isAtomic(Element<std::string>(_configuration[i]))) - atomicStates.push_back(_configuration[i]); - } - atomicStates.to_document_order(); - - for (unsigned int i = 0; i < atomicStates.size(); i++) { - Element<std::string> state(atomicStates[i]); - while(true) { - NodeSet<std::string> transitions = filterChildElements(_nsInfo.xmlNSPrefix + "transition", state); - for (unsigned int k = 0; k < transitions.size(); k++) { - if (isEnabledTransition(Element<std::string>(transitions[k]), event)) { - enabledTransitions.push_back(transitions[k]); - goto NEXT_ATOMIC; - } - } - if (state.getParentNode() && state.getParentNode().getNodeType() == Node_base::ELEMENT_NODE) { - state = Element<std::string>(state.getParentNode()); - } else { - goto NEXT_ATOMIC; - } - } - NEXT_ATOMIC:; - } - + Arabica::XPath::NodeSet<std::string> enabledTransitions; + + NodeSet<std::string> atomicStates; + for (unsigned int i = 0; i < _configuration.size(); i++) { + if (isAtomic(Element<std::string>(_configuration[i]))) + atomicStates.push_back(_configuration[i]); + } + atomicStates.to_document_order(); + + for (unsigned int i = 0; i < atomicStates.size(); i++) { + Element<std::string> state(atomicStates[i]); + while(true) { + NodeSet<std::string> transitions = filterChildElements(_nsInfo.xmlNSPrefix + "transition", state); + for (unsigned int k = 0; k < transitions.size(); k++) { + if (isEnabledTransition(Element<std::string>(transitions[k]), event)) { + enabledTransitions.push_back(transitions[k]); + goto NEXT_ATOMIC; + } + } + if (state.getParentNode() && state.getParentNode().getNodeType() == Node_base::ELEMENT_NODE) { + state = Element<std::string>(state.getParentNode()); + } else { + goto NEXT_ATOMIC; + } + } +NEXT_ATOMIC: + ; + } + #if 0 - std::cerr << "Enabled transitions for '" << event << "': " << std::endl; - for (int i = 0; i < enabledTransitions.size(); i++) { - std::cerr << enabledTransitions[i] << std::endl << "----" << std::endl; - } - std::cerr << std::endl; + std::cerr << "Enabled transitions for '" << event << "': " << std::endl; + for (int i = 0; i < enabledTransitions.size(); i++) { + std::cerr << enabledTransitions[i] << std::endl << "----" << std::endl; + } + std::cerr << std::endl; #endif - enabledTransitions = removeConflictingTransitions(enabledTransitions); + enabledTransitions = removeConflictingTransitions(enabledTransitions); #if 0 - std::cerr << "Non-conflicting transitions for '" << event << "': " << std::endl; - for (int i = 0; i < enabledTransitions.size(); i++) { - std::cerr << enabledTransitions[i] << std::endl << "----" << std::endl; - } - std::cerr << std::endl; + std::cerr << "Non-conflicting transitions for '" << event << "': " << std::endl; + for (int i = 0; i < enabledTransitions.size(); i++) { + std::cerr << enabledTransitions[i] << std::endl << "----" << std::endl; + } + std::cerr << std::endl; #endif - return enabledTransitions; + return enabledTransitions; } Arabica::XPath::NodeSet<std::string> InterpreterImpl::selectEventlessTransitions() { - Arabica::XPath::NodeSet<std::string> enabledTransitions; - - NodeSet<std::string> atomicStates; - for (unsigned int i = 0; i < _configuration.size(); i++) { - if (isAtomic(Element<std::string>(_configuration[i]))) - atomicStates.push_back(_configuration[i]); - } - atomicStates.to_document_order(); - - for (unsigned int i = 0; i < atomicStates.size(); i++) { - Element<std::string> state(atomicStates[i]); - while(true) { - NodeSet<std::string> transitions = filterChildElements(_nsInfo.xmlNSPrefix + "transition", state); - for (unsigned int k = 0; k < transitions.size(); k++) { - Element<std::string> transElem(transitions[k]); - if (!HAS_ATTR(transElem, "event") && hasConditionMatch(transElem)) { - enabledTransitions.push_back(transitions[k]); - goto NEXT_ATOMIC; - } - } - if (state.getParentNode() && state.getParentNode().getNodeType() == Node_base::ELEMENT_NODE) { - state = Element<std::string>(state.getParentNode()); - } else { - goto NEXT_ATOMIC; - } - } - NEXT_ATOMIC:; - } - + Arabica::XPath::NodeSet<std::string> enabledTransitions; + + NodeSet<std::string> atomicStates; + for (unsigned int i = 0; i < _configuration.size(); i++) { + if (isAtomic(Element<std::string>(_configuration[i]))) + atomicStates.push_back(_configuration[i]); + } + atomicStates.to_document_order(); + + for (unsigned int i = 0; i < atomicStates.size(); i++) { + Element<std::string> state(atomicStates[i]); + while(true) { + NodeSet<std::string> transitions = filterChildElements(_nsInfo.xmlNSPrefix + "transition", state); + for (unsigned int k = 0; k < transitions.size(); k++) { + Element<std::string> transElem(transitions[k]); + if (!HAS_ATTR(transElem, "event") && hasConditionMatch(transElem)) { + enabledTransitions.push_back(transitions[k]); + goto NEXT_ATOMIC; + } + } + if (state.getParentNode() && state.getParentNode().getNodeType() == Node_base::ELEMENT_NODE) { + state = Element<std::string>(state.getParentNode()); + } else { + goto NEXT_ATOMIC; + } + } +NEXT_ATOMIC: + ; + } + #if 0 - std::cerr << "Enabled eventless transitions: " << std::endl; - for (int i = 0; i < enabledTransitions.size(); i++) { - std::cerr << enabledTransitions[i] << std::endl << "----" << std::endl; - } - std::cerr << std::endl; + std::cerr << "Enabled eventless transitions: " << std::endl; + for (int i = 0; i < enabledTransitions.size(); i++) { + std::cerr << enabledTransitions[i] << std::endl << "----" << std::endl; + } + std::cerr << std::endl; #endif - enabledTransitions = removeConflictingTransitions(enabledTransitions); - return enabledTransitions; + enabledTransitions = removeConflictingTransitions(enabledTransitions); + return enabledTransitions; } - + #endif bool InterpreterImpl::isEnabledTransition(const Element<std::string>& transition, const std::string& event) { @@ -1362,7 +1364,7 @@ void InterpreterImpl::reset() { _isInitialized = false; _stable = false; - _dataModel = DataModel(); + _dataModel = DataModel(); setInterpreterState(USCXML_INSTANTIATED); } @@ -1403,7 +1405,7 @@ void InterpreterImpl::setupDOM() { } resolveXIncludes(); - + // find scxml element if (!_scxml) { NodeList<std::string> scxmls; @@ -1428,15 +1430,15 @@ void InterpreterImpl::setupDOM() { // normalize document - // make sure every state has an id - not required per spec, but needed for us - Arabica::XPath::NodeSet<std::string> states = getAllStates(); - for (int i = 0; i < states.size(); i++) { - Arabica::DOM::Element<std::string> stateElem = Arabica::DOM::Element<std::string>(states[i]); - if (!stateElem.hasAttribute("id")) { - stateElem.setAttribute("id", UUID::getUUID()); - } - _cachedStates[ATTR(stateElem, "id")] = stateElem; - } + // make sure every state has an id - not required per spec, but needed for us + Arabica::XPath::NodeSet<std::string> states = getAllStates(); + for (int i = 0; i < states.size(); i++) { + Arabica::DOM::Element<std::string> stateElem = Arabica::DOM::Element<std::string>(states[i]); + if (!stateElem.hasAttribute("id")) { + stateElem.setAttribute("id", UUID::getUUID()); + } + _cachedStates[ATTR(stateElem, "id")] = stateElem; + } // make sure every invoke has an idlocation or id - actually required! Arabica::XPath::NodeSet<std::string> invokes = _xpath.evaluate("//" + _nsInfo.xpathPrefix + "invoke", _scxml).asNodeSet(); @@ -1464,7 +1466,7 @@ void InterpreterImpl::setupDOM() { void InterpreterImpl::resolveXIncludes() { std::string xIncludeNS = _nsInfo.getXMLPrefixForNS("http://www.w3.org/2001/XInclude"); - + // no element in namespace for xinclude, don't bother searching if (xIncludeNS.size() == 0) return; @@ -1479,7 +1481,7 @@ void InterpreterImpl::resolveXIncludes() { // recursively resolve includes resolveXIncludes(includeChain, mergedNs, xIncludeNS, URL::asBaseURL(_sourceURL), Element<std::string>(xincludes[i])); } - + // update NameSpaceInfo and reinit xpath resolver _nsInfo = NameSpaceInfo(mergedNs); _xpath.setNamespaceContext(*_nsInfo.getNSContext()); @@ -1487,10 +1489,10 @@ void InterpreterImpl::resolveXIncludes() { } void InterpreterImpl::resolveXIncludes(std::list<std::string> includeChain, - std::map<std::string, std::string>& mergedNS, - const std::string& xIncludeNS, - const URL& baseURL, - const Arabica::DOM::Element<std::string>& xinclude) { + std::map<std::string, std::string>& mergedNS, + const std::string& xIncludeNS, + const URL& baseURL, + const Arabica::DOM::Element<std::string>& xinclude) { URL src = baseURL; NodeSet<std::string> newNodes; @@ -1502,7 +1504,7 @@ void InterpreterImpl::resolveXIncludes(std::list<std::string> includeChain, goto TRY_WITH_FALLBACK; } } - + if (std::find(includeChain.begin(), includeChain.end(), src.asString()) != includeChain.end()) { std::stringstream incErr; incErr << ("Ignoring recursive inclusion of '" + src.asString() + " via:") << std::endl; @@ -1513,7 +1515,7 @@ void InterpreterImpl::resolveXIncludes(std::list<std::string> includeChain, return; } includeChain.push_back(src.asString()); - + if (HAS_ATTR(xinclude, "accept")) { src.addOutHeader("Accept", ATTR_CAST(xinclude, "accept")); } @@ -1528,7 +1530,7 @@ void InterpreterImpl::resolveXIncludes(std::list<std::string> includeChain, } catch (Event e) { goto TRY_WITH_FALLBACK; } - + if (HAS_ATTR(xinclude, "parse") && iequals(ATTR(xinclude, "parse"), "text")) { // parse as text Text<std::string> textNode = _document.createTextNode(includedContent); @@ -1547,7 +1549,7 @@ void InterpreterImpl::resolveXIncludes(std::list<std::string> includeChain, if (mergedNS.find("http://www.w3.org/2005/07/scxml") == mergedNS.end() && xiParser.nameSpace.find("http://www.w3.org/2005/07/scxml") != xiParser.nameSpace.end()) { LOG(ERROR) << ("Error for '" + DOMUtils::xPathForNode(xinclude) + "': root document uses implicit SCXML namespace without prefix, included document does map it to prefix '" + xiParser.nameSpace["http://www.w3.org/2005/07/scxml"] + "', trying xi:fallback"); goto TRY_WITH_FALLBACK; - + } // merge namespaces to prefix mappings @@ -1558,7 +1560,7 @@ void InterpreterImpl::resolveXIncludes(std::list<std::string> includeChain, LOG(ERROR) << ("Error for '" + DOMUtils::xPathForNode(xinclude) + "': Cannot map namespace '" + nsIter->first + "' to prefix '" + nsIter->second + "', it is already mapped to prefix '" + mergedNS[nsIter->first] + "', trying xi:fallback"); goto TRY_WITH_FALLBACK; } - + // same prefix but different nsURL for (std::map<std::string, std::string>::iterator currIter = mergedNS.begin(); currIter != mergedNS.end(); currIter++) { if (currIter->second == nsIter->second && currIter->first != nsIter->first) { @@ -1568,7 +1570,7 @@ void InterpreterImpl::resolveXIncludes(std::list<std::string> includeChain, } mergedNS[nsIter->first] = nsIter->second; } - + // import DOM Node<std::string> imported = _document.importNode(xiParser.getDocument().getDocumentElement(), true); newNodes.push_back(imported); @@ -1580,8 +1582,7 @@ void InterpreterImpl::resolveXIncludes(std::list<std::string> includeChain, LOG(ERROR) << "No href attribute for xi:xinclude at '" << DOMUtils::xPathForNode(xinclude) << "', trying xi:fallback"; goto TRY_WITH_FALLBACK; } -TRY_WITH_FALLBACK: - { +TRY_WITH_FALLBACK: { NodeSet<std::string> fallbacks = filterChildElements(xIncludeNS + "fallback", xinclude); if (fallbacks.size() > 0) { LOG(WARNING) << "Using xi:fallback for '" << DOMUtils::xPathForNode(xinclude) << "'"; @@ -1605,7 +1606,7 @@ REMOVE_AND_RECURSE: } } } - + void InterpreterImpl::init() { // make sure we have a factory if none was set before if (_factory == NULL) @@ -1741,26 +1742,26 @@ void InterpreterImpl::internalDoneSend(const Arabica::DOM::Element<std::string>& Event event; - if (doneData) { - processParamChilds(doneData, event.params); - Arabica::XPath::NodeSet<std::string> contents = filterChildElements(_nsInfo.xmlNSPrefix + "content", doneData); - if (contents.size() > 1) - LOG(ERROR) << "Only a single content element is allowed for send elements - using first one"; - if (contents.size() > 0) { - std::string expr; - processContentElement(Element<std::string>(contents[0]), event.dom, event.content, expr); - if (expr.length() > 0) { - try { - event.content =_dataModel.evalAsString(expr); - } catch (Event e) { - e.name = "error.execution"; - e.dom = contents[0]; - receiveInternal(e); - } - } - } - } - + if (doneData) { + processParamChilds(doneData, event.params); + Arabica::XPath::NodeSet<std::string> contents = filterChildElements(_nsInfo.xmlNSPrefix + "content", doneData); + if (contents.size() > 1) + LOG(ERROR) << "Only a single content element is allowed for send elements - using first one"; + if (contents.size() > 0) { + std::string expr; + processContentElement(Element<std::string>(contents[0]), event.dom, event.content, expr); + if (expr.length() > 0) { + try { + event.content =_dataModel.evalAsString(expr); + } catch (Event e) { + e.name = "error.execution"; + e.dom = contents[0]; + receiveInternal(e); + } + } + } + } + event.name = "done.state." + ATTR_CAST(state, "id"); // parent?! receiveInternal(event); @@ -2267,15 +2268,15 @@ void InterpreterImpl::invoke(const Arabica::DOM::Element<std::string>& element) USCXML_MONITOR_CALLBACK3(afterInvoking, Arabica::DOM::Element<std::string>(element), invokeReq.invokeid) // this is out of draft but so useful to know when an invoker started - if (HAS_ATTR(element, "callback")) { - std::string callback = ATTR(element, "callback"); - if (callback.size() > 0) { - Event invSuccess; - invSuccess.name = callback + "." + invokeReq.invokeid; - receive(invSuccess); - } - } - + if (HAS_ATTR(element, "callback")) { + std::string callback = ATTR(element, "callback"); + if (callback.size() > 0) { + Event invSuccess; + invSuccess.name = callback + "." + invokeReq.invokeid; + receive(invSuccess); + } + } + } catch(boost::bad_lexical_cast e) { LOG(ERROR) << "Exception caught while sending invoke request to invoker " << invokeReq.invokeid << ": " << e.what(); @@ -2717,7 +2718,7 @@ void InterpreterImpl::finalizeAndAutoForwardCurrentEvent() { // Yes do so, see test229! // if (!boost::equals(_currEvent.getOriginType(), "http://www.w3.org/TR/scxml/#SCXMLEventProcessor")) // LOG(ERROR) << _sessionId << " auto forwards " << _currEvent.name << " to " << invokeIter->first << std::endl; - invokeIter->second.send(_currEvent); + invokeIter->second.send(_currEvent); } catch (const std::exception &e) { LOG(ERROR) << "Exception caught while sending event to invoker " << invokeIter->first << ": " << e.what(); } catch(...) { @@ -2964,10 +2965,10 @@ Arabica::XPath::NodeSet<std::string> InterpreterImpl::getInitialStates(Arabica:: NodeSet<std::string> initElems = filterChildElements(_nsInfo.xmlNSPrefix + "initial", state); if(initElems.size() > 0 && !iequals(ATTR_CAST(initElems[0], "generated"), "true")) { NodeSet<std::string> initTrans = filterChildElements(_nsInfo.xmlNSPrefix + "transition", initElems[0]); - if (initTrans.size() > 0) { - return getTargetStates(Element<std::string>(initTrans[0])); - } - } + if (initTrans.size() > 0) { + return getTargetStates(Element<std::string>(initTrans[0])); + } + } // first child state Arabica::XPath::NodeSet<std::string> initStates; @@ -2986,77 +2987,77 @@ Arabica::XPath::NodeSet<std::string> InterpreterImpl::getInitialStates(Arabica:: } NodeSet<std::string> InterpreterImpl::getReachableStates() { - /** Check which states are reachable */ - - NodeSet<std::string> reachable; - reachable.push_back(_scxml); - - bool hasChanges = true; - - while (hasChanges) { - // iterate initials and transitions until stable, unneccerily iterates complete reachable set everytime - - hasChanges = false; - // reachable per initial attribute or document order - size will increase as we append new states - for (int i = 0; i < reachable.size(); i++) { - // get the state's initial states - Element<std::string> state = Element<std::string>(reachable[i]); - try { - NodeSet<std::string> initials = getInitialStates(state); - for (int j = 0; j < initials.size(); j++) { - Element<std::string> initial = Element<std::string>(initials[j]); - if (!InterpreterImpl::isMember(initial, reachable)) { - reachable.push_back(initial); - hasChanges = true; - } - } - } catch (Event e) { - } - } - - // reachable per target attribute in transitions - for (int i = 0; i < reachable.size(); i++) { - Element<std::string> state = Element<std::string>(reachable[i]); - NodeSet<std::string> transitions = InterpreterImpl::filterChildElements(_nsInfo.xmlNSPrefix + "transition", state, false); - for (int j = 0; j < transitions.size(); j++) { - Element<std::string> transition = Element<std::string>(transitions[j]); - try { - NodeSet<std::string> targets = getTargetStates(transition); - for (int k = 0; k < targets.size(); k++) { - Element<std::string> target = Element<std::string>(targets[k]); - if (!InterpreterImpl::isMember(target, reachable)) { - reachable.push_back(target); - hasChanges = true; - } - } - } catch (Event e) { - } - } - } - - // reachable via a reachable child state - for (int i = 0; i < reachable.size(); i++) { - Element<std::string> state = Element<std::string>(reachable[i]); - if (InterpreterImpl::isAtomic(state)) { - // iterate the states parents - Node<std::string> parent = state.getParentNode(); - while(parent && parent.getNodeType() == Node_base::ELEMENT_NODE) { - Element<std::string> parentElem = Element<std::string>(parent); - if (!InterpreterImpl::isState(parentElem)) { - break; - } - if (!InterpreterImpl::isMember(parentElem, reachable)) { - reachable.push_back(parent); - hasChanges = true; - } - parent = parent.getParentNode(); - } - } - } - } - - - return reachable; + /** Check which states are reachable */ + + NodeSet<std::string> reachable; + reachable.push_back(_scxml); + + bool hasChanges = true; + + while (hasChanges) { + // iterate initials and transitions until stable, unneccerily iterates complete reachable set everytime + + hasChanges = false; + // reachable per initial attribute or document order - size will increase as we append new states + for (int i = 0; i < reachable.size(); i++) { + // get the state's initial states + Element<std::string> state = Element<std::string>(reachable[i]); + try { + NodeSet<std::string> initials = getInitialStates(state); + for (int j = 0; j < initials.size(); j++) { + Element<std::string> initial = Element<std::string>(initials[j]); + if (!InterpreterImpl::isMember(initial, reachable)) { + reachable.push_back(initial); + hasChanges = true; + } + } + } catch (Event e) { + } + } + + // reachable per target attribute in transitions + for (int i = 0; i < reachable.size(); i++) { + Element<std::string> state = Element<std::string>(reachable[i]); + NodeSet<std::string> transitions = InterpreterImpl::filterChildElements(_nsInfo.xmlNSPrefix + "transition", state, false); + for (int j = 0; j < transitions.size(); j++) { + Element<std::string> transition = Element<std::string>(transitions[j]); + try { + NodeSet<std::string> targets = getTargetStates(transition); + for (int k = 0; k < targets.size(); k++) { + Element<std::string> target = Element<std::string>(targets[k]); + if (!InterpreterImpl::isMember(target, reachable)) { + reachable.push_back(target); + hasChanges = true; + } + } + } catch (Event e) { + } + } + } + + // reachable via a reachable child state + for (int i = 0; i < reachable.size(); i++) { + Element<std::string> state = Element<std::string>(reachable[i]); + if (InterpreterImpl::isAtomic(state)) { + // iterate the states parents + Node<std::string> parent = state.getParentNode(); + while(parent && parent.getNodeType() == Node_base::ELEMENT_NODE) { + Element<std::string> parentElem = Element<std::string>(parent); + if (!InterpreterImpl::isState(parentElem)) { + break; + } + if (!InterpreterImpl::isMember(parentElem, reachable)) { + reachable.push_back(parent); + hasChanges = true; + } + parent = parent.getParentNode(); + } + } + } + } + + + return reachable; } @@ -3105,7 +3106,7 @@ NodeSet<std::string> InterpreterImpl::getTargetStates(const Arabica::XPath::Node } #define ISWHITESPACE(char) (isspace(char)) - + std::list<std::string> InterpreterImpl::tokenize(const std::string& line, const char sep, bool trimWhiteSpace) { std::list<std::string> tokens; @@ -3116,7 +3117,9 @@ std::list<std::string> InterpreterImpl::tokenize(const std::string& line, const if (i > 0 && start < i) { tokens.push_back(line.substr(start, i - start)); } - while(line[i] == sep || (trimWhiteSpace && ISWHITESPACE(line[i]))) { i++; } // skip multiple occurences of seperator and whitespaces + while(line[i] == sep || (trimWhiteSpace && ISWHITESPACE(line[i]))) { + i++; // skip multiple occurences of seperator and whitespaces + } start = i; } else if (i + 1 == line.size()) { tokens.push_back(line.substr(start, i + 1 - start)); @@ -3196,7 +3199,7 @@ NodeSet<std::string> InterpreterImpl::filterChildElements(const std::string& tag return filteredChildElems; } - + NodeSet<std::string> InterpreterImpl::filterChildType(const Node_base::Type type, const NodeSet<std::string>& nodeSet, bool recurse) { NodeSet<std::string> filteredChildType; for (unsigned int i = 0; i < nodeSet.size(); i++) { @@ -3265,10 +3268,10 @@ NodeSet<std::string> InterpreterImpl::getProperAncestors(const Arabica::DOM::Nod bool InterpreterImpl::isDescendant(const Arabica::DOM::Node<std::string>& s1, const Arabica::DOM::Node<std::string>& s2) { - if (!s1 || !s2) - return false; + if (!s1 || !s2) + return false; - Arabica::DOM::Node<std::string> parent = s1.getParentNode(); + Arabica::DOM::Node<std::string> parent = s1.getParentNode(); while(parent) { if (s2 == parent) return true; diff --git a/src/uscxml/Interpreter.h b/src/uscxml/Interpreter.h index d857902..fa02eca 100644 --- a/src/uscxml/Interpreter.h +++ b/src/uscxml/Interpreter.h @@ -185,7 +185,7 @@ public: void cloneFrom(InterpreterImpl* other); void cloneFrom(boost::shared_ptr<InterpreterImpl> other); virtual void writeTo(std::ostream& stream); - + // TODO: We need to move the destructor to the implementations to make these pure virtual virtual InterpreterState interpret(); virtual InterpreterState step(int waitForMS = 0); @@ -214,7 +214,7 @@ public: _baseURL[_scxml] = baseURL; } } - + std::string getSourceURL() { return _sourceURL.asString(); } @@ -347,7 +347,7 @@ public: void addDataModelExtension(DataModelExtension* ext) { _dataModelExtensions.insert(ext); } - + void setInvoker(const std::string& invokeId, Invoker invoker) { _dontDestructOnUninvoke.insert(invokeId); _invokers[invokeId] = invoker; @@ -388,7 +388,7 @@ public: Arabica::XPath::NodeSet<std::string> getDocumentInitialTransitions(); Arabica::XPath::NodeSet<std::string> getInitialStates(Arabica::DOM::Element<std::string> state = Arabica::DOM::Element<std::string>()); - Arabica::XPath::NodeSet<std::string> getReachableStates(); + Arabica::XPath::NodeSet<std::string> getReachableStates(); static Arabica::XPath::NodeSet<std::string> getChildStates(const Arabica::DOM::Node<std::string>& state); static Arabica::XPath::NodeSet<std::string> getChildStates(const Arabica::XPath::NodeSet<std::string>& state); @@ -407,7 +407,7 @@ public: return tokenize(idRefs, ' ', true); } static std::list<std::string> tokenize(const std::string& line, const char seperator = ' ', bool trimWhiteSpace = false); - + static std::string spaceNormalize(const std::string& text); static bool nameMatch(const std::string& eventDescs, const std::string& event); Arabica::DOM::Node<std::string> findLCCA(const Arabica::XPath::NodeSet<std::string>& states); @@ -431,10 +431,10 @@ protected: void setupDOM(); void resolveXIncludes(); void resolveXIncludes(std::list<std::string> includeChain, - std::map<std::string, std::string>& mergedNS, - const std::string& xIncludeNS, - const URL& baseURL, - const Arabica::DOM::Element<std::string>& xinclude); + std::map<std::string, std::string>& mergedNS, + const std::string& xIncludeNS, + const URL& baseURL, + const Arabica::DOM::Element<std::string>& xinclude); virtual void setupIOProcessors(); std::list<InterpreterIssue> validate(); @@ -448,7 +448,7 @@ protected: virtual Arabica::XPath::NodeSet<std::string> selectEventlessTransitions(); virtual Arabica::XPath::NodeSet<std::string> selectTransitions(const std::string& event); virtual bool isEnabledTransition(const Arabica::DOM::Element<std::string>& transition, const std::string& event); - + void setInterpreterState(InterpreterState newState); bool _stable; @@ -540,13 +540,13 @@ protected: IOProcessor getIOProcessor(const std::string& type); const URL& getBaseURLForNode(const Arabica::DOM::Node<std::string>& node); - + std::map<std::string, IOProcessor> _ioProcessors; std::map<std::string, std::pair<InterpreterImpl*, SendRequest> > _sendIds; std::map<std::string, Invoker> _invokers; std::map<Arabica::DOM::Node<std::string>, ExecutableContent> _executableContent; std::set<DataModelExtension*> _dataModelExtensions; - + std::map<std::pair<Arabica::DOM::Node<std::string>, Arabica::DOM::Node<std::string> >, Arabica::XPath::NodeSet<std::string> > _cachedProperAncestors; std::map<Arabica::DOM::Element<std::string>, Arabica::XPath::NodeSet<std::string> > _cachedTargets; std::map<std::string, Arabica::DOM::Element<std::string> > _cachedStates; @@ -563,9 +563,9 @@ class USCXML_API Interpreter { public: static Interpreter fromDOM(const Arabica::DOM::Document<std::string>& dom, const NameSpaceInfo& nameSpaceInfo, - const std::string& sourceURL); + const std::string& sourceURL); static Interpreter fromXML(const std::string& xml, - const std::string& sourceURL); + const std::string& sourceURL); static Interpreter fromURL(const std::string& URL); static Interpreter fromClone(const Interpreter& other); @@ -592,13 +592,13 @@ public: } virtual void writeTo(std::ostream& stream) { - TIME_BLOCK + TIME_BLOCK return _impl->writeTo(stream); } void reset() { #ifdef BUILD_PROFILING - timer = Timer(); + timer = Timer(); #endif return _impl->reset(); } @@ -621,19 +621,19 @@ public: }; InterpreterState step(int waitForMS = 0) { - TIME_BLOCK + TIME_BLOCK return _impl->step(waitForMS); }; InterpreterState step(bool blocking) { - TIME_BLOCK + TIME_BLOCK if (blocking) return _impl->step(-1); return _impl->step(0); }; std::list<InterpreterIssue> validate() { - TIME_BLOCK + TIME_BLOCK return _impl->validate(); } @@ -720,41 +720,41 @@ public: return _impl->getFactory(); } Arabica::XPath::NodeSet<std::string> getNodeSetForXPath(const std::string& xpathExpr) { - TIME_BLOCK + TIME_BLOCK return _impl->getNodeSetForXPath(xpathExpr); } void inline receiveInternal(const Event& event) { - TIME_BLOCK + TIME_BLOCK return _impl->receiveInternal(event); } void receive(const Event& event, bool toFront = false) { - TIME_BLOCK + TIME_BLOCK return _impl->receive(event, toFront); } Event getCurrentEvent() { - TIME_BLOCK + TIME_BLOCK return _impl->getCurrentEvent(); } bool isInState(const std::string& stateId) { - TIME_BLOCK + TIME_BLOCK return _impl->isInState(stateId); } Arabica::XPath::NodeSet<std::string> getConfiguration() { - TIME_BLOCK + TIME_BLOCK return _impl->getConfiguration(); } Arabica::XPath::NodeSet<std::string> getBasicConfiguration() { - TIME_BLOCK + TIME_BLOCK return _impl->getBasicConfiguration(); } void setInitalConfiguration(const std::list<std::string>& states) { - TIME_BLOCK + TIME_BLOCK return _impl->setInitalConfiguration(states); } @@ -791,23 +791,23 @@ public: } bool runOnMainThread(int fps, bool blocking = true) { - TIME_BLOCK + TIME_BLOCK return _impl->runOnMainThread(fps, blocking); } bool hasLegalConfiguration() { - TIME_BLOCK + TIME_BLOCK return _impl->hasLegalConfiguration(); } bool isLegalConfiguration(const Arabica::XPath::NodeSet<std::string>& config) { - TIME_BLOCK + TIME_BLOCK return _impl->isLegalConfiguration(config); } bool isLegalConfiguration(const std::list<std::string>& config) { - TIME_BLOCK - return _impl->isLegalConfiguration(config); + TIME_BLOCK + return _impl->isLegalConfiguration(config); } boost::shared_ptr<InterpreterImpl> getImpl() const { @@ -818,7 +818,7 @@ public: static void addInstance(boost::shared_ptr<InterpreterImpl> instance); #ifdef BUILD_PROFILING - Timer timer; + Timer timer; #endif protected: @@ -836,7 +836,7 @@ protected: class USCXML_API InterpreterMonitor { public: - InterpreterMonitor() : _copyToInvokers(false) {} + InterpreterMonitor() : _copyToInvokers(false) {} virtual ~InterpreterMonitor() {} virtual void beforeProcessingEvent(Interpreter interpreter, const Event& event) {} @@ -869,17 +869,17 @@ public: virtual void reportIssue(Interpreter interpreter, const InterpreterIssue& issue) {} - void copyToInvokers(bool copy) { - _copyToInvokers = copy; - } + void copyToInvokers(bool copy) { + _copyToInvokers = copy; + } - bool copyToInvokers() { - return _copyToInvokers; - } + bool copyToInvokers() { + return _copyToInvokers; + } protected: - bool _copyToInvokers; - + bool _copyToInvokers; + }; class StateTransitionMonitor : public uscxml::InterpreterMonitor { @@ -892,7 +892,7 @@ public: virtual void beforeEnteringState(uscxml::Interpreter interpreter, const Arabica::DOM::Element<std::string>& state, bool moreComing); protected: - static tthread::recursive_mutex _mutex; + static tthread::recursive_mutex _mutex; void printNodeSet(const Arabica::XPath::NodeSet<std::string>& config); Arabica::XPath::NodeSet<std::string> exitingStates; Arabica::XPath::NodeSet<std::string> enteringStates; diff --git a/src/uscxml/InterpreterInfo.h b/src/uscxml/InterpreterInfo.h index 490e414..190ac0c 100644 --- a/src/uscxml/InterpreterInfo.h +++ b/src/uscxml/InterpreterInfo.h @@ -30,72 +30,72 @@ namespace uscxml { - + class USCXML_API NameSpaceInfo { public: - NameSpaceInfo() : nsContext(NULL) { - init(std::map<std::string, std::string>()); - } - - NameSpaceInfo(const std::map<std::string, std::string>& nsInfo) : nsContext(NULL) { - init(nsInfo); - } - - NameSpaceInfo(const NameSpaceInfo& other) : nsContext(NULL) { - init(other.nsInfo); - } - - virtual ~NameSpaceInfo() { - if (nsContext) - delete nsContext; - } - - NameSpaceInfo& operator=( const NameSpaceInfo& other ) { - init(other.nsInfo); - return *this; - } - - void setPrefix(Arabica::DOM::Element<std::string> element) { - if (nsURL.size() > 0) - element.setPrefix(nsToPrefix[nsURL]); - } - - void setPrefix(Arabica::DOM::Attr<std::string> attribute) { - if (nsURL.size() > 0) - attribute.setPrefix(nsToPrefix[nsURL]); - } - - std::string getXMLPrefixForNS(const std::string& ns) const { - if (nsToPrefix.find(ns) != nsToPrefix.end() && nsToPrefix.at(ns).size()) - return nsToPrefix.at(ns) + ":"; - return ""; - } - - const Arabica::XPath::StandardNamespaceContext<std::string>* getNSContext() { - return nsContext; - } - - std::string nsURL; // ough to be "http://www.w3.org/2005/07/scxml" but maybe empty - std::string xpathPrefix; // prefix mapped for xpath, "scxml" is _xmlNSPrefix is empty but _nsURL set - std::string xmlNSPrefix; // the actual prefix for elements in the xml file - std::map<std::string, std::string> nsToPrefix; // prefixes for a given namespace - std::map<std::string, std::string> nsInfo; // all xmlns mappings - + NameSpaceInfo() : nsContext(NULL) { + init(std::map<std::string, std::string>()); + } + + NameSpaceInfo(const std::map<std::string, std::string>& nsInfo) : nsContext(NULL) { + init(nsInfo); + } + + NameSpaceInfo(const NameSpaceInfo& other) : nsContext(NULL) { + init(other.nsInfo); + } + + virtual ~NameSpaceInfo() { + if (nsContext) + delete nsContext; + } + + NameSpaceInfo& operator=( const NameSpaceInfo& other ) { + init(other.nsInfo); + return *this; + } + + void setPrefix(Arabica::DOM::Element<std::string> element) { + if (nsURL.size() > 0) + element.setPrefix(nsToPrefix[nsURL]); + } + + void setPrefix(Arabica::DOM::Attr<std::string> attribute) { + if (nsURL.size() > 0) + attribute.setPrefix(nsToPrefix[nsURL]); + } + + std::string getXMLPrefixForNS(const std::string& ns) const { + if (nsToPrefix.find(ns) != nsToPrefix.end() && nsToPrefix.at(ns).size()) + return nsToPrefix.at(ns) + ":"; + return ""; + } + + const Arabica::XPath::StandardNamespaceContext<std::string>* getNSContext() { + return nsContext; + } + + std::string nsURL; // ough to be "http://www.w3.org/2005/07/scxml" but maybe empty + std::string xpathPrefix; // prefix mapped for xpath, "scxml" is _xmlNSPrefix is empty but _nsURL set + std::string xmlNSPrefix; // the actual prefix for elements in the xml file + std::map<std::string, std::string> nsToPrefix; // prefixes for a given namespace + std::map<std::string, std::string> nsInfo; // all xmlns mappings + private: - Arabica::XPath::StandardNamespaceContext<std::string>* nsContext; - - void init(const std::map<std::string, std::string>& nsInfo); + Arabica::XPath::StandardNamespaceContext<std::string>* nsContext; + + void init(const std::map<std::string, std::string>& nsInfo); }; class USCXML_API InterpreterInfo { public: - virtual NameSpaceInfo getNameSpaceInfo() const = 0; - virtual const std::string& getName() = 0; - virtual const std::string& getSessionId() = 0; - virtual const std::map<std::string, IOProcessor>& getIOProcessors() = 0; - virtual bool isInState(const std::string& stateId) = 0; - virtual Arabica::DOM::Document<std::string> getDocument() const = 0; - virtual const std::map<std::string, Invoker>& getInvokers() = 0; + virtual NameSpaceInfo getNameSpaceInfo() const = 0; + virtual const std::string& getName() = 0; + virtual const std::string& getSessionId() = 0; + virtual const std::map<std::string, IOProcessor>& getIOProcessors() = 0; + virtual bool isInState(const std::string& stateId) = 0; + virtual Arabica::DOM::Document<std::string> getDocument() const = 0; + virtual const std::map<std::string, Invoker>& getInvokers() = 0; }; } diff --git a/src/uscxml/URL.cpp b/src/uscxml/URL.cpp index 38cb780..67a6e37 100644 --- a/src/uscxml/URL.cpp +++ b/src/uscxml/URL.cpp @@ -66,7 +66,7 @@ void URL::dump() { } std::cout << std::endl << std::endl; } - + std::string URL::tmpDir() { // try hard to find a temporary directory const char* tmpDir = NULL; @@ -564,7 +564,7 @@ URLFetcher::URLFetcher() { _isStarted = false; _envProxy = NULL; _multiHandle = curl_multi_init(); - + // read proxy information from environment // CURLOPT_PROXY; // CURLOPT_PROXY_TRANSFER_MODE; @@ -575,13 +575,13 @@ URLFetcher::URLFetcher() { // CURLOPT_PROXYTYPE; // CURLOPT_PROXYUSERNAME; // CURLOPT_PROXYUSERPWD; - + /* see http://curl.haxx.se/libcurl/c/CURLOPT_PROXY.html e.g. 'socks5://bob:marley@localhost:12345' */ _envProxy = getenv("USCXML_PROXY"); - + #if 0 bool unsupported = false; CURLcode curlError; @@ -600,7 +600,7 @@ URLFetcher::URLFetcher() { if (envProxy) (curlError = curl_easy_setopt(_multiHandle, CURLOPT_PROXY, envProxy)) == CURLE_OK || LOG(ERROR) << "Cannot set curl proxy: " << curl_easy_strerror(curlError); - + /* set transfer mode (;type=<a|i>) when doing FTP via an HTTP proxy */ if (envProxyTransferMode) (curlError = curl_easy_setopt(_multiHandle, CURLOPT_PROXY_TRANSFER_MODE, envProxyTransferMode)) == CURLE_OK || @@ -612,7 +612,7 @@ URLFetcher::URLFetcher() { if (envProxyAuth) (curlError = curl_easy_setopt(_multiHandle, CURLOPT_PROXYAUTH, envProxyAuth)) == CURLE_OK || LOG(ERROR) << "Cannot set curl proxy authentication: " << curl_easy_strerror(curlError); - + #if 0 /* This points to a linked list of headers used for proxy requests only, struct curl_slist kind */ @@ -620,7 +620,7 @@ URLFetcher::URLFetcher() { (curlError = curl_easy_setopt(_multiHandle, CURLOPT_PROXYHEADER, envProxyHeader)) == CURLE_OK || LOG(ERROR) << "Cannot set curl proxy header: " << curl_easy_strerror(curlError); #endif - + /* "name" and "pwd" to use with Proxy when fetching. */ if (envProxyUsername) (curlError = curl_easy_setopt(_multiHandle, CURLOPT_PROXYUSERNAME, envProxyUsername)) == CURLE_OK || @@ -628,13 +628,13 @@ URLFetcher::URLFetcher() { if (envProxyPassword) (curlError = curl_easy_setopt(_multiHandle, CURLOPT_PROXYPASSWORD, envProxyPassword)) == CURLE_OK || LOG(ERROR) << "Cannot set curl proxy password: " << curl_easy_strerror(curlError); - + /* Port of the proxy, can be set in the proxy string as well with: "[host]:[port]" */ if (envProxyPort) (curlError = curl_easy_setopt(_multiHandle, CURLOPT_PROXYPORT, envProxyPort)) == CURLE_OK || LOG(ERROR) << "Cannot set curl proxy port: " << curl_easy_strerror(curlError); - + #if 0 /* indicates type of proxy. accepted values are CURLPROXY_HTTP (default), CURLPROXY_SOCKS4, CURLPROXY_SOCKS4A and CURLPROXY_SOCKS5. */ @@ -642,7 +642,7 @@ URLFetcher::URLFetcher() { (curlError = curl_easy_setopt(_multiHandle, CURLOPT_PROXYTYPE, envProxyType)) == CURLE_OK || LOG(ERROR) << "Cannot set curl proxy type: " << curl_easy_strerror(curlError); #endif - + /* "user:password" to use with proxy. */ if (envProxyUserPwd) (curlError = curl_easy_setopt(_multiHandle, CURLOPT_PROXYUSERPWD, envProxyUserPwd)) == CURLE_OK || diff --git a/src/uscxml/URL.h b/src/uscxml/URL.h index 20a22cc..1da2e7f 100644 --- a/src/uscxml/URL.h +++ b/src/uscxml/URL.h @@ -232,14 +232,14 @@ public: } void dump(); - + void addMonitor(URLMonitor* monitor) { _impl->addMonitor(monitor); } void removeMonitor(URLMonitor* monitor) { _impl->removeMonitor(monitor); } - + bool downloadFailed() { return _impl->downloadFailed(); } @@ -286,7 +286,7 @@ public: operator std::string() const { return asString(); } - + protected: void downloadStarted() { return _impl->downloadStarted(); diff --git a/src/uscxml/concurrency/DelayedEventQueue.cpp b/src/uscxml/concurrency/DelayedEventQueue.cpp index ca43c8e..897e99d 100644 --- a/src/uscxml/concurrency/DelayedEventQueue.cpp +++ b/src/uscxml/concurrency/DelayedEventQueue.cpp @@ -100,12 +100,12 @@ void DelayedEventQueue::addEvent(std::string eventId, void (*callback)(void*, co } void DelayedEventQueue::cancelAllEvents() { - tthread::lock_guard<tthread::recursive_mutex> lock(_mutex); - while(_callbackData.size() > 0) { - event_del(_callbackData[_callbackData.begin()->first].event); - event_free(_callbackData[_callbackData.begin()->first].event); - _callbackData.erase(_callbackData.begin()); - } + tthread::lock_guard<tthread::recursive_mutex> lock(_mutex); + while(_callbackData.size() > 0) { + event_del(_callbackData[_callbackData.begin()->first].event); + event_free(_callbackData[_callbackData.begin()->first].event); + _callbackData.erase(_callbackData.begin()); + } } void DelayedEventQueue::cancelEvent(std::string eventId) { @@ -131,7 +131,7 @@ void DelayedEventQueue::stop() { if (_thread) { _thread->join(); delete _thread; - _thread = NULL; + _thread = NULL; } } diff --git a/src/uscxml/concurrency/DelayedEventQueue.h b/src/uscxml/concurrency/DelayedEventQueue.h index d89b715..7c2789f 100644 --- a/src/uscxml/concurrency/DelayedEventQueue.h +++ b/src/uscxml/concurrency/DelayedEventQueue.h @@ -57,8 +57,8 @@ public: void addEvent(std::string eventId, int fd, short opMask, void (*callback)(void*, const std::string eventId), void* userData, bool persist = true); void addEvent(std::string eventId, void (*callback)(void*, const std::string eventId), uint32_t delayMs, void* userData, bool persist = false); - void cancelEvent(std::string eventId); - void cancelAllEvents(); + void cancelEvent(std::string eventId); + void cancelAllEvents(); void start(); void stop(); diff --git a/src/uscxml/concurrency/Timer.cpp b/src/uscxml/concurrency/Timer.cpp index 2835173..77b712f 100644 --- a/src/uscxml/concurrency/Timer.cpp +++ b/src/uscxml/concurrency/Timer.cpp @@ -14,102 +14,102 @@ #define USECS_PER_SEC 1000000 #if _POSIX_TIMERS > 0 && defined(_POSIX_MONOTONIC_CLOCK) - // If we have it, use clock_gettime and CLOCK_MONOTONIC. +// If we have it, use clock_gettime and CLOCK_MONOTONIC. - #include <time.h> +#include <time.h> - double uscxml::Timer::monotonic_seconds() { - struct timespec time; - // Note: Make sure to link with -lrt to define clock_gettime. - clock_gettime(CLOCK_MONOTONIC, &time); - return ((double) time.tv_sec) + ((double) time.tv_nsec / (NANOS_PER_SECF)); - } +double uscxml::Timer::monotonic_seconds() { + struct timespec time; + // Note: Make sure to link with -lrt to define clock_gettime. + clock_gettime(CLOCK_MONOTONIC, &time); + return ((double) time.tv_sec) + ((double) time.tv_nsec / (NANOS_PER_SECF)); +} #elif defined(__APPLE__) - // If we don't have CLOCK_MONOTONIC, we might be on a Mac. There we instead - // use mach_absolute_time(). +// If we don't have CLOCK_MONOTONIC, we might be on a Mac. There we instead +// use mach_absolute_time(). - #include <mach/mach_time.h> +#include <mach/mach_time.h> - static mach_timebase_info_data_t info; - static void __attribute__((constructor)) init_info() { - mach_timebase_info(&info); - } +static mach_timebase_info_data_t info; +static void __attribute__((constructor)) init_info() { + mach_timebase_info(&info); +} - double uscxml::Timer::monotonic_seconds() { - uint64_t time = mach_absolute_time(); - double dtime = (double) time; - dtime *= (double) info.numer; - dtime /= (double) info.denom; - return dtime / NANOS_PER_SECF; - } +double uscxml::Timer::monotonic_seconds() { + uint64_t time = mach_absolute_time(); + double dtime = (double) time; + dtime *= (double) info.numer; + dtime /= (double) info.denom; + return dtime / NANOS_PER_SECF; +} #elif defined(_MSC_VER) - // On Windows, use QueryPerformanceCounter and QueryPerformanceFrequency. +// On Windows, use QueryPerformanceCounter and QueryPerformanceFrequency. #define NOMINMAX - #include <windows.h> +#include <windows.h> - static double PCFreq = 0.0; +static double PCFreq = 0.0; __int64 CounterStart = 0; - double uscxml::Timer::monotonic_seconds() { - if (CounterStart == 0) { - // Accoring to http://stackoverflow.com/a/1739265/447288, this will - // properly initialize the QueryPerformanceCounter. +double uscxml::Timer::monotonic_seconds() { + if (CounterStart == 0) { + // Accoring to http://stackoverflow.com/a/1739265/447288, this will + // properly initialize the QueryPerformanceCounter. - LARGE_INTEGER li; - int has_qpc = QueryPerformanceFrequency(&li); + LARGE_INTEGER li; + int has_qpc = QueryPerformanceFrequency(&li); - PCFreq = ((double) li.QuadPart) / 1000.0; - } - LARGE_INTEGER li; - QueryPerformanceCounter(&li); - return double(li.QuadPart - CounterStart)/PCFreq; - } + PCFreq = ((double) li.QuadPart) / 1000.0; + } + LARGE_INTEGER li; + QueryPerformanceCounter(&li); + return double(li.QuadPart - CounterStart)/PCFreq; +} #else - // Fall back to rdtsc. The reason we don't use clock() is this scary message - // from the man page: - // "On several other implementations, the value returned by clock() also - // includes the times of any children whose status has been collected via - // wait(2) (or another wait-type call)." - // - // Also, clock() only has microsecond accuracy. - // - // This whitepaper offered excellent advice on how to use rdtscp for - // profiling: http://download.intel.com/embedded/software/IA/324264.pdf - // - // Unfortunately, we can't follow its advice exactly with our semantics, - // so we're just going to use rdtscp with cpuid. - // - // Note that rdtscp will only be available on new processors. - - #include <stdint.h> - - static inline uint64_t rdtsc() { - uint32_t hi, lo; - asm volatile("rdtscp\n" - "movl %%edx, %0\n" - "movl %%eax, %1\n" - "cpuid" - : "=r" (hi), "=r" (lo) : : "%rax", "%rbx", "%rcx", "%rdx"); - return (((uint64_t)hi) << 32) | (uint64_t)lo; - } - - static uint64_t rdtsc_per_sec = 0; - static void __attribute__((constructor)) init_rdtsc_per_sec() { - uint64_t before, after; - - before = rdtsc(); - usleep(USECS_PER_SEC); - after = rdtsc(); - - rdtsc_per_sec = after - before; - } - - double uscxml::Timer::monotonic_seconds() { - return (double) rdtsc() / (double) rdtsc_per_sec; - } +// Fall back to rdtsc. The reason we don't use clock() is this scary message +// from the man page: +// "On several other implementations, the value returned by clock() also +// includes the times of any children whose status has been collected via +// wait(2) (or another wait-type call)." +// +// Also, clock() only has microsecond accuracy. +// +// This whitepaper offered excellent advice on how to use rdtscp for +// profiling: http://download.intel.com/embedded/software/IA/324264.pdf +// +// Unfortunately, we can't follow its advice exactly with our semantics, +// so we're just going to use rdtscp with cpuid. +// +// Note that rdtscp will only be available on new processors. + +#include <stdint.h> + +static inline uint64_t rdtsc() { + uint32_t hi, lo; + asm volatile("rdtscp\n" + "movl %%edx, %0\n" + "movl %%eax, %1\n" + "cpuid" + : "=r" (hi), "=r" (lo) : : "%rax", "%rbx", "%rcx", "%rdx"); + return (((uint64_t)hi) << 32) | (uint64_t)lo; +} + +static uint64_t rdtsc_per_sec = 0; +static void __attribute__((constructor)) init_rdtsc_per_sec() { + uint64_t before, after; + + before = rdtsc(); + usleep(USECS_PER_SEC); + after = rdtsc(); + + rdtsc_per_sec = after - before; +} + +double uscxml::Timer::monotonic_seconds() { + return (double) rdtsc() / (double) rdtsc_per_sec; +} #endif diff --git a/src/uscxml/concurrency/Timer.h b/src/uscxml/concurrency/Timer.h index 217f68f..1ecfeb2 100644 --- a/src/uscxml/concurrency/Timer.h +++ b/src/uscxml/concurrency/Timer.h @@ -18,56 +18,56 @@ namespace uscxml { class USCXML_API Timer { public: - - static double monotonic_seconds(); - - Timer() { - invocations = 0; - elapsed = 0; - } - - void start() { - if (invocations == 0) { - started = monotonic_seconds(); - } - invocations++; - } - - void reset() { - elapsed = 0; + + static double monotonic_seconds(); + + Timer() { + invocations = 0; + elapsed = 0; + } + + void start() { + if (invocations == 0) { + started = monotonic_seconds(); } - - void stop() { - if (invocations == 0) - return; - - invocations--; - if (invocations == 0) { - elapsed += monotonic_seconds() - started; - } - } - - ~Timer() { - } - double elapsed; + invocations++; + } + + void reset() { + elapsed = 0; + } + + void stop() { + if (invocations == 0) + return; + + invocations--; + if (invocations == 0) { + elapsed += monotonic_seconds() - started; + } + } + + ~Timer() { + } + double elapsed; protected: - size_t invocations; - double started; + size_t invocations; + double started; }; - + class USCXML_API Measurement { public: - Measurement(Timer* timer) : timer(timer) { - timer->start(); - } + Measurement(Timer* timer) : timer(timer) { + timer->start(); + } - ~Measurement() { - timer->stop(); - } + ~Measurement() { + timer->stop(); + } protected: - Timer* timer; + Timer* timer; }; } diff --git a/src/uscxml/debug/Complexity.cpp b/src/uscxml/debug/Complexity.cpp index de01831..29d7706 100644 --- a/src/uscxml/debug/Complexity.cpp +++ b/src/uscxml/debug/Complexity.cpp @@ -33,15 +33,15 @@ std::list<std::set<Element<std::string> > > Complexity::getAllConfigurations(con std::string nsPrefix = (root.getPrefix().size() > 0 ? root.getPrefix() + ":" : ""); std::string localName = root.getLocalName(); bool isAtomic = true; - + NodeList<std::string> children = root.getChildNodes(); for (int i = 0; i < children.getLength(); i++) { if (children.item(i).getNodeType() != Node_base::ELEMENT_NODE) continue; Element<std::string> childElem(children.item(i)); if (childElem.getTagName() == nsPrefix + "state" || - childElem.getTagName() == nsPrefix + "parallel" || - childElem.getTagName() == nsPrefix + "final") { + childElem.getTagName() == nsPrefix + "parallel" || + childElem.getTagName() == nsPrefix + "final") { // nested child state std::list<std::set<Element<std::string> > > nestedConfigurations = getAllConfigurations(childElem); isAtomic = false; @@ -50,7 +50,7 @@ std::list<std::set<Element<std::string> > > Complexity::getAllConfigurations(con std::list<std::set<Element<std::string> > > combinedConfigurations; for (std::list<std::set<Element<std::string> > >::iterator existIter = allConfigurations.begin(); existIter != allConfigurations.end(); existIter++) { std::set<Element<std::string> > existingConfig = *existIter; - + for (std::list<std::set<Element<std::string> > >::iterator newIter = nestedConfigurations.begin(); newIter != nestedConfigurations.end(); newIter++) { std::set<Element<std::string> > newConfig = *newIter; @@ -81,13 +81,13 @@ std::list<std::set<Element<std::string> > > Complexity::getAllConfigurations(con } return allConfigurations; } - + std::map<size_t, size_t> Complexity::getTransitionHistogramm(const Arabica::DOM::Element<std::string>& root) { std::map<size_t, size_t> histogram; std::string nameSpace; - + std::list<std::set<Element<std::string> > > allConfig = Complexity::getAllConfigurations(root); - + // for every legal configuration, count the transitions for (std::list<std::set<Element<std::string> > >::iterator confIter = allConfig.begin(); confIter != allConfig.end(); confIter++) { NodeSet<std::string> configNodeSet; @@ -106,29 +106,29 @@ std::map<size_t, size_t> Complexity::getTransitionHistogramm(const Arabica::DOM: uint64_t Complexity::stateMachineComplexity(InterpreterImpl* interpreter, Variant variant) { - Arabica::DOM::Element<std::string> root = interpreter->getDocument().getDocumentElement(); - - Arabica::XPath::NodeSet<std::string> reachable; - - if (variant & IGNORE_UNREACHABLE) { - reachable = interpreter->getReachableStates(); - } - - Complexity complexity = calculateStateMachineComplexity(root, reachable); + Arabica::DOM::Element<std::string> root = interpreter->getDocument().getDocumentElement(); + + Arabica::XPath::NodeSet<std::string> reachable; + + if (variant & IGNORE_UNREACHABLE) { + reachable = interpreter->getReachableStates(); + } + + Complexity complexity = calculateStateMachineComplexity(root, reachable); uint64_t value = complexity.value; - - if (!(variant & IGNORE_HISTORY)) { + + if (!(variant & IGNORE_HISTORY)) { for (std::list<uint64_t>::const_iterator histIter = complexity.history.begin(); histIter != complexity.history.end(); histIter++) { value *= *histIter; } } - - if (!(variant & IGNORE_NESTED_DATA)) { + + if (!(variant & IGNORE_NESTED_DATA)) { bool ignoreNestedData = false; if (root.getLocalName() == "scxml" && (!HAS_ATTR_CAST(root, "binding") || boost::to_lower_copy(ATTR_CAST(root, "binding")) == "early")) { ignoreNestedData = true; } - + if (!ignoreNestedData) { uint64_t power = complexity.nestedData; while(power--) { @@ -136,17 +136,17 @@ uint64_t Complexity::stateMachineComplexity(InterpreterImpl* interpreter, Varian } } } - + return value; } - + Complexity Complexity::calculateStateMachineComplexity(const Arabica::DOM::Element<std::string>& root, const Arabica::XPath::NodeSet<std::string>& reachable) { Complexity complexity; bool hasFlatHistory = false; bool hasDeepHistory = false; bool hasNestedData = false; - + Arabica::DOM::NodeList<std::string> childElems = root.getChildNodes(); for (int i = 0; i < childElems.getLength(); i++) { if (childElems.item(i).getNodeType() != Node_base::ELEMENT_NODE) @@ -170,10 +170,10 @@ Complexity Complexity::calculateStateMachineComplexity(const Arabica::DOM::Eleme if (hasNestedData) complexity.nestedData++; - - if (reachable.size() > 0 && !InterpreterImpl::isMember(root, reachable)) { - return 0; - } else if (InterpreterImpl::isCompound(root) || TAGNAME(root) == "scxml") { + + if (reachable.size() > 0 && !InterpreterImpl::isMember(root, reachable)) { + return 0; + } else if (InterpreterImpl::isCompound(root) || TAGNAME(root) == "scxml") { // compounds can be in any of the child state -> add NodeSet<std::string> childs = InterpreterImpl::getChildStates(root); for (int i = 0; i < childs.size(); i++) { diff --git a/src/uscxml/debug/Complexity.h b/src/uscxml/debug/Complexity.h index 76330fd..de05692 100644 --- a/src/uscxml/debug/Complexity.h +++ b/src/uscxml/debug/Complexity.h @@ -27,35 +27,35 @@ namespace uscxml { class USCXML_API Complexity { public: - + enum Variant { IGNORE_NOTHING = 0x0000, IGNORE_HISTORY = 0x0001, IGNORE_NESTED_DATA = 0x0002, IGNORE_UNREACHABLE = 0x0004, }; - + Complexity() : value(0), nestedData(0) {} Complexity(uint64_t value) : value(value), nestedData(0) {} - + Complexity& operator+=(const Complexity& rhs) { value += rhs.value; nestedData += rhs.nestedData; history.insert(history.end(), rhs.history.begin(), rhs.history.end()); return *this; } - + Complexity& operator*=(const Complexity& rhs) { value *= rhs.value; nestedData += rhs.nestedData; history.insert(history.end(), rhs.history.begin(), rhs.history.end()); return *this; } - - static uint64_t stateMachineComplexity(const Interpreter& interpreter, Complexity::Variant variant = IGNORE_NOTHING) { - return stateMachineComplexity(interpreter.getImpl().get()); - } - static uint64_t stateMachineComplexity(InterpreterImpl* interpreter, Complexity::Variant variant = IGNORE_NOTHING); + + static uint64_t stateMachineComplexity(const Interpreter& interpreter, Complexity::Variant variant = IGNORE_NOTHING) { + return stateMachineComplexity(interpreter.getImpl().get()); + } + static uint64_t stateMachineComplexity(InterpreterImpl* interpreter, Complexity::Variant variant = IGNORE_NOTHING); static std::list<std::set<Arabica::DOM::Element<std::string> > > getAllConfigurations(const Arabica::DOM::Element<std::string>& root); static std::map<size_t, size_t> getTransitionHistogramm(const Arabica::DOM::Element<std::string>& root); @@ -69,8 +69,8 @@ protected: }; inline Complexity::Variant operator | ( Complexity::Variant lhs, Complexity::Variant rhs ) { - // Cast to int first otherwise we'll just end up recursing - return static_cast< Complexity::Variant >( static_cast< int >( lhs ) | static_cast< int >( rhs ) ); + // Cast to int first otherwise we'll just end up recursing + return static_cast< Complexity::Variant >( static_cast< int >( lhs ) | static_cast< int >( rhs ) ); } } diff --git a/src/uscxml/debug/InterpreterIssue.cpp b/src/uscxml/debug/InterpreterIssue.cpp index 49b595d..7d55f3a 100644 --- a/src/uscxml/debug/InterpreterIssue.cpp +++ b/src/uscxml/debug/InterpreterIssue.cpp @@ -59,35 +59,36 @@ void assembleNodeSets(const std::string nsPrefix, const Node<std::string>& node, * Can the given states ever appear in an active configuration? */ bool hasLegalCompletion(const NodeSet<std::string>& states) { - if (states.size() < 2) - return true; - - // iterate every pair - for (unsigned int outer = 0; outer < states.size() - 1; outer++) { - Element<std::string> s1(states[outer]); - for (unsigned int inner = outer + 1; inner < states.size(); inner++) { - Element<std::string> s2(states[inner]); - Node<std::string> parent; - - // ok to be directly ancestorally related - if (InterpreterImpl::isDescendant(s1, s2) || InterpreterImpl::isDescendant(s2, s1)) - goto NEXT_PAIR; - - // find least common ancestor - parent = s1.getParentNode(); - while(parent && parent.getNodeType() == Node_base::ELEMENT_NODE) { - if (InterpreterImpl::isDescendant(s2, parent)) { - if (InterpreterImpl::isParallel(Element<std::string>(parent))) - goto NEXT_PAIR; - } - parent = parent.getParentNode(); - } - - return false; - NEXT_PAIR:; - } - } - return true; + if (states.size() < 2) + return true; + + // iterate every pair + for (unsigned int outer = 0; outer < states.size() - 1; outer++) { + Element<std::string> s1(states[outer]); + for (unsigned int inner = outer + 1; inner < states.size(); inner++) { + Element<std::string> s2(states[inner]); + Node<std::string> parent; + + // ok to be directly ancestorally related + if (InterpreterImpl::isDescendant(s1, s2) || InterpreterImpl::isDescendant(s2, s1)) + goto NEXT_PAIR; + + // find least common ancestor + parent = s1.getParentNode(); + while(parent && parent.getNodeType() == Node_base::ELEMENT_NODE) { + if (InterpreterImpl::isDescendant(s2, parent)) { + if (InterpreterImpl::isParallel(Element<std::string>(parent))) + goto NEXT_PAIR; + } + parent = parent.getParentNode(); + } + + return false; +NEXT_PAIR: + ; + } + } + return true; } std::list<InterpreterIssue> InterpreterIssue::forInterpreter(InterpreterImpl* interpreter) { @@ -170,8 +171,8 @@ std::list<InterpreterIssue> InterpreterIssue::forInterpreter(InterpreterImpl* in allExecContents.push_back(cancels); NodeSet<std::string> allElements; - allElements.push_back(scxmls); - allElements.push_back(allStates); + allElements.push_back(scxmls); + allElements.push_back(allStates); allElements.push_back(allExecContents); allElements.push_back(transitions); allElements.push_back(initials); @@ -191,26 +192,26 @@ std::list<InterpreterIssue> InterpreterIssue::forInterpreter(InterpreterImpl* in execContentSet.insert("elseif"); execContentSet.insert("else"); execContentSet.insert("foreach"); - execContentSet.insert("raise"); + execContentSet.insert("raise"); execContentSet.insert("send"); - execContentSet.insert("cancel"); + execContentSet.insert("cancel"); execContentSet.insert("assign"); execContentSet.insert("script"); - execContentSet.insert("log"); - - // required attributes per standard - std::map<std::string, std::set<std::string> > reqAttr; - reqAttr["scxml"].insert("xmlns"); - reqAttr["scxml"].insert("version"); - reqAttr["raise"].insert("event"); - reqAttr["if"].insert("cond"); - reqAttr["elseif"].insert("cond"); - reqAttr["foreach"].insert("array"); - reqAttr["foreach"].insert("item"); - reqAttr["data"].insert("id"); - reqAttr["assign"].insert("location"); - reqAttr["param"].insert("name"); - + execContentSet.insert("log"); + + // required attributes per standard + std::map<std::string, std::set<std::string> > reqAttr; + reqAttr["scxml"].insert("xmlns"); + reqAttr["scxml"].insert("version"); + reqAttr["raise"].insert("event"); + reqAttr["if"].insert("cond"); + reqAttr["elseif"].insert("cond"); + reqAttr["foreach"].insert("array"); + reqAttr["foreach"].insert("item"); + reqAttr["data"].insert("id"); + reqAttr["assign"].insert("location"); + reqAttr["param"].insert("name"); + // these are the valid children for elements in the SCXML namespace as per specification std::map<std::string, std::set<std::string> > validChildren; validChildren["scxml"].insert("state"); @@ -224,11 +225,11 @@ std::list<InterpreterIssue> InterpreterIssue::forInterpreter(InterpreterImpl* in validChildren["state"].insert("transition"); validChildren["state"].insert("state"); validChildren["state"].insert("parallel"); - validChildren["state"].insert("history"); - validChildren["state"].insert("datamodel"); - validChildren["state"].insert("invoke"); - validChildren["state"].insert("initial"); - validChildren["state"].insert("final"); + validChildren["state"].insert("history"); + validChildren["state"].insert("datamodel"); + validChildren["state"].insert("invoke"); + validChildren["state"].insert("initial"); + validChildren["state"].insert("final"); validChildren["parallel"].insert("onentry"); validChildren["parallel"].insert("onexit"); @@ -351,7 +352,7 @@ std::list<InterpreterIssue> InterpreterIssue::forInterpreter(InterpreterImpl* in if (targetIds.size() == 0) { issues.push_back(InterpreterIssue("Transition has empty target state list", transition, InterpreterIssue::USCXML_ISSUE_FATAL)); } - + for (std::list<std::string>::iterator targetIter = targetIds.begin(); targetIter != targetIds.end(); targetIter++) { if (seenStates.find(*targetIter) == seenStates.end()) { issues.push_back(InterpreterIssue("Transition has non-existant target state with id '" + *targetIter + "'", transition, InterpreterIssue::USCXML_ISSUE_FATAL)); @@ -405,25 +406,25 @@ NEXT_TRANSITION: } } - // check for useless history elements - { - for (int i = 0; i < histories.size(); i++) { - Element<std::string> history = Element<std::string>(histories[i]); - if (!history.getParentNode() || history.getParentNode().getNodeType() != Node_base::ELEMENT_NODE) - continue; // syntax check will have catched this - Element<std::string> parent(history.getParentNode()); - if (InterpreterImpl::isAtomic(parent)) { - issues.push_back(InterpreterIssue("Useless history '" + ATTR(history, "id") + "' in atomic state", history, InterpreterIssue::USCXML_ISSUE_INFO)); - continue; - } - std::list<std::set<Arabica::DOM::Element<std::string> > > configs = Complexity::getAllConfigurations(parent); - if (configs.size() <= 1) { - issues.push_back(InterpreterIssue("Useless history '" + ATTR(history, "id") + "' in state with single legal configuration", history, InterpreterIssue::USCXML_ISSUE_INFO)); - continue; - } - } - } - + // check for useless history elements + { + for (int i = 0; i < histories.size(); i++) { + Element<std::string> history = Element<std::string>(histories[i]); + if (!history.getParentNode() || history.getParentNode().getNodeType() != Node_base::ELEMENT_NODE) + continue; // syntax check will have catched this + Element<std::string> parent(history.getParentNode()); + if (InterpreterImpl::isAtomic(parent)) { + issues.push_back(InterpreterIssue("Useless history '" + ATTR(history, "id") + "' in atomic state", history, InterpreterIssue::USCXML_ISSUE_INFO)); + continue; + } + std::list<std::set<Arabica::DOM::Element<std::string> > > configs = Complexity::getAllConfigurations(parent); + if (configs.size() <= 1) { + issues.push_back(InterpreterIssue("Useless history '" + ATTR(history, "id") + "' in state with single legal configuration", history, InterpreterIssue::USCXML_ISSUE_INFO)); + continue; + } + } + } + // check for valid initial attribute { NodeSet<std::string> withInitialAttr; @@ -434,121 +435,122 @@ NEXT_TRANSITION: Element<std::string> state = Element<std::string>(withInitialAttr[i]); if (HAS_ATTR(state, "initial")) { - NodeSet<std::string> childs; - childs.push_back(InterpreterImpl::filterChildElements(_nsInfo.xmlNSPrefix + "state", state, true)); - childs.push_back(InterpreterImpl::filterChildElements(_nsInfo.xmlNSPrefix + "parallel", state, true)); - childs.push_back(InterpreterImpl::filterChildElements(_nsInfo.xmlNSPrefix + "final", state, true)); - childs.push_back(InterpreterImpl::filterChildElements(_nsInfo.xmlNSPrefix + "history", state, true)); + NodeSet<std::string> childs; + childs.push_back(InterpreterImpl::filterChildElements(_nsInfo.xmlNSPrefix + "state", state, true)); + childs.push_back(InterpreterImpl::filterChildElements(_nsInfo.xmlNSPrefix + "parallel", state, true)); + childs.push_back(InterpreterImpl::filterChildElements(_nsInfo.xmlNSPrefix + "final", state, true)); + childs.push_back(InterpreterImpl::filterChildElements(_nsInfo.xmlNSPrefix + "history", state, true)); - std::list<std::string> intials = InterpreterImpl::tokenizeIdRefs(ATTR(state, "initial")); + std::list<std::string> intials = InterpreterImpl::tokenizeIdRefs(ATTR(state, "initial")); for (std::list<std::string>::iterator initIter = intials.begin(); initIter != intials.end(); initIter++) { if (seenStates.find(*initIter) == seenStates.end()) { issues.push_back(InterpreterIssue("Initial attribute has invalid target state with id '" + *initIter + "'", state, InterpreterIssue::USCXML_ISSUE_FATAL)); continue; } - // value of the 'initial' attribute [..] must be descendants of the containing <state> or <parallel> element - if (!InterpreterImpl::isMember(seenStates[*initIter], childs)) { - issues.push_back(InterpreterIssue("Initial attribute references non-child state '" + *initIter + "'", state, InterpreterIssue::USCXML_ISSUE_FATAL)); - } + // value of the 'initial' attribute [..] must be descendants of the containing <state> or <parallel> element + if (!InterpreterImpl::isMember(seenStates[*initIter], childs)) { + issues.push_back(InterpreterIssue("Initial attribute references non-child state '" + *initIter + "'", state, InterpreterIssue::USCXML_ISSUE_FATAL)); + } } } } } - // check for legal configuration of target sets - { - std::map<Element<std::string>, std::string > targetIdSets; - for (int i = 0; i < transitions.size(); i++) { - Element<std::string> transition = Element<std::string>(transitions[i]); - - if (HAS_ATTR(transition, "target")) { - targetIdSets[transition] = ATTR(transition, "target"); - } - } - - for (int i = 0; i < initials.size(); i++) { - Element<std::string> initial = Element<std::string>(initials[i]); - - if (HAS_ATTR(initial, "target")) { - targetIdSets[initial] = ATTR(initial, "target"); - } - } - - for (int i = 0; i < allStates.size(); i++) { - Element<std::string> state = Element<std::string>(allStates[i]); - - if (HAS_ATTR(state, "initial")) { - targetIdSets[state] = ATTR(state, "initial"); - } - } - - for (std::map<Element<std::string>, std::string >::iterator setIter = targetIdSets.begin(); - setIter != targetIdSets.end(); - setIter++) { - NodeSet<std::string> targets; - std::list<std::string> targetIds = InterpreterImpl::tokenizeIdRefs(setIter->second); - for (std::list<std::string>::iterator tgtIter = targetIds.begin(); tgtIter != targetIds.end(); tgtIter++) { - if (seenStates.find(*tgtIter) == seenStates.end()) - goto NEXT_SET; - targets.push_back(seenStates[*tgtIter]); - } - if (!hasLegalCompletion(targets)) { - issues.push_back(InterpreterIssue("Target states cause illegal configuration", setIter->first, InterpreterIssue::USCXML_ISSUE_FATAL)); - } - NEXT_SET:; - } - } - - // check for valid initial transition - { - NodeSet<std::string> initTrans; + // check for legal configuration of target sets + { + std::map<Element<std::string>, std::string > targetIdSets; + for (int i = 0; i < transitions.size(); i++) { + Element<std::string> transition = Element<std::string>(transitions[i]); + + if (HAS_ATTR(transition, "target")) { + targetIdSets[transition] = ATTR(transition, "target"); + } + } + + for (int i = 0; i < initials.size(); i++) { + Element<std::string> initial = Element<std::string>(initials[i]); + + if (HAS_ATTR(initial, "target")) { + targetIdSets[initial] = ATTR(initial, "target"); + } + } + + for (int i = 0; i < allStates.size(); i++) { + Element<std::string> state = Element<std::string>(allStates[i]); + + if (HAS_ATTR(state, "initial")) { + targetIdSets[state] = ATTR(state, "initial"); + } + } + + for (std::map<Element<std::string>, std::string >::iterator setIter = targetIdSets.begin(); + setIter != targetIdSets.end(); + setIter++) { + NodeSet<std::string> targets; + std::list<std::string> targetIds = InterpreterImpl::tokenizeIdRefs(setIter->second); + for (std::list<std::string>::iterator tgtIter = targetIds.begin(); tgtIter != targetIds.end(); tgtIter++) { + if (seenStates.find(*tgtIter) == seenStates.end()) + goto NEXT_SET; + targets.push_back(seenStates[*tgtIter]); + } + if (!hasLegalCompletion(targets)) { + issues.push_back(InterpreterIssue("Target states cause illegal configuration", setIter->first, InterpreterIssue::USCXML_ISSUE_FATAL)); + } +NEXT_SET: + ; + } + } + + // check for valid initial transition + { + NodeSet<std::string> initTrans; // initTrans.push_back(InterpreterImpl::filterChildElements(_nsInfo.xmlNSPrefix + "transition", histories, true)); - - for (int i = 0; i < initials.size(); i++) { - Element<std::string> initial = Element<std::string>(initials[i]); - NodeSet<std::string> initTransitions = InterpreterImpl::filterChildElements(_nsInfo.xmlNSPrefix + "transition", initial, true); - if (initTransitions.size() != 1) { - issues.push_back(InterpreterIssue("Initial element must define exactly one transition", initial, InterpreterIssue::USCXML_ISSUE_FATAL)); - } - initTrans.push_back(initTransitions); - - } - - for (int i = 0; i < initTrans.size(); i++) { - Element<std::string> transition = Element<std::string>(initTrans[i]); - - /* In a conformant SCXML document, this transition must not contain 'cond' or 'event' attributes, and must specify a non-null 'target' - * whose value is a valid state specification consisting solely of descendants of the containing state - */ - - if (HAS_ATTR(transition, "cond")) { - issues.push_back(InterpreterIssue("Initial transition cannot have a condition", transition, InterpreterIssue::USCXML_ISSUE_FATAL)); - } - if (HAS_ATTR(transition, "event")) { - issues.push_back(InterpreterIssue("Initial transition cannot be eventful", transition, InterpreterIssue::USCXML_ISSUE_FATAL)); - } - - if (!transition.getParentNode() || !transition.getParentNode().getParentNode() || transition.getParentNode().getParentNode().getNodeType() != Node_base::ELEMENT_NODE) - continue; // syntax will catch this one - Element<std::string> state(transition.getParentNode().getParentNode()); - if (!InterpreterImpl::isState(state)) - continue; // syntax will catch this one - - NodeSet<std::string> childs; - childs.push_back(InterpreterImpl::filterChildElements(_nsInfo.xmlNSPrefix + "state", state, true)); - childs.push_back(InterpreterImpl::filterChildElements(_nsInfo.xmlNSPrefix + "parallel", state, true)); - childs.push_back(InterpreterImpl::filterChildElements(_nsInfo.xmlNSPrefix + "final", state, true)); - childs.push_back(InterpreterImpl::filterChildElements(_nsInfo.xmlNSPrefix + "history", state, true)); - - std::list<std::string> intials = InterpreterImpl::tokenizeIdRefs(ATTR(transition, "target")); - for (std::list<std::string>::iterator initIter = intials.begin(); initIter != intials.end(); initIter++) { - // the 'target' of a <transition> inside an <initial> or <history> element: all the states must be descendants of the containing <state> or <parallel> element - if (!InterpreterImpl::isMember(seenStates[*initIter], childs)) { - issues.push_back(InterpreterIssue("Target of initial transition references non-child state '" + *initIter + "'", transition, InterpreterIssue::USCXML_ISSUE_FATAL)); - } - } - } - } + + for (int i = 0; i < initials.size(); i++) { + Element<std::string> initial = Element<std::string>(initials[i]); + NodeSet<std::string> initTransitions = InterpreterImpl::filterChildElements(_nsInfo.xmlNSPrefix + "transition", initial, true); + if (initTransitions.size() != 1) { + issues.push_back(InterpreterIssue("Initial element must define exactly one transition", initial, InterpreterIssue::USCXML_ISSUE_FATAL)); + } + initTrans.push_back(initTransitions); + + } + + for (int i = 0; i < initTrans.size(); i++) { + Element<std::string> transition = Element<std::string>(initTrans[i]); + + /* In a conformant SCXML document, this transition must not contain 'cond' or 'event' attributes, and must specify a non-null 'target' + * whose value is a valid state specification consisting solely of descendants of the containing state + */ + + if (HAS_ATTR(transition, "cond")) { + issues.push_back(InterpreterIssue("Initial transition cannot have a condition", transition, InterpreterIssue::USCXML_ISSUE_FATAL)); + } + if (HAS_ATTR(transition, "event")) { + issues.push_back(InterpreterIssue("Initial transition cannot be eventful", transition, InterpreterIssue::USCXML_ISSUE_FATAL)); + } + + if (!transition.getParentNode() || !transition.getParentNode().getParentNode() || transition.getParentNode().getParentNode().getNodeType() != Node_base::ELEMENT_NODE) + continue; // syntax will catch this one + Element<std::string> state(transition.getParentNode().getParentNode()); + if (!InterpreterImpl::isState(state)) + continue; // syntax will catch this one + + NodeSet<std::string> childs; + childs.push_back(InterpreterImpl::filterChildElements(_nsInfo.xmlNSPrefix + "state", state, true)); + childs.push_back(InterpreterImpl::filterChildElements(_nsInfo.xmlNSPrefix + "parallel", state, true)); + childs.push_back(InterpreterImpl::filterChildElements(_nsInfo.xmlNSPrefix + "final", state, true)); + childs.push_back(InterpreterImpl::filterChildElements(_nsInfo.xmlNSPrefix + "history", state, true)); + + std::list<std::string> intials = InterpreterImpl::tokenizeIdRefs(ATTR(transition, "target")); + for (std::list<std::string>::iterator initIter = intials.begin(); initIter != intials.end(); initIter++) { + // the 'target' of a <transition> inside an <initial> or <history> element: all the states must be descendants of the containing <state> or <parallel> element + if (!InterpreterImpl::isMember(seenStates[*initIter], childs)) { + issues.push_back(InterpreterIssue("Target of initial transition references non-child state '" + *initIter + "'", transition, InterpreterIssue::USCXML_ISSUE_FATAL)); + } + } + } + } // check that all invokers exists @@ -618,22 +620,22 @@ NEXT_TRANSITION: for (int i = 0; i < allElements.size(); i++) { Element<std::string> element = Element<std::string>(allElements[i]); std::string localName = LOCALNAME(element); - - if (reqAttr.find(localName) != reqAttr.end()) { - for (std::set<std::string>::const_iterator reqIter = reqAttr[localName].begin(); - reqIter != reqAttr[localName].end(); reqIter++) { - if (!HAS_ATTR(element, *reqIter)) { - issues.push_back(InterpreterIssue("Element " + localName + " is missing required attribute '" + *reqIter + "'", element, InterpreterIssue::USCXML_ISSUE_WARNING)); - } - if (HAS_ATTR(element, *reqIter) && ATTR(element, *reqIter).size() == 0) { - issues.push_back(InterpreterIssue("Required attribute '" + *reqIter + "' of element " + localName + " is empty", element, InterpreterIssue::USCXML_ISSUE_WARNING)); - } - } - } - - if (localName == "scxml") // can be anywhere: <assign>, <content>, <other:embed> - continue; - + + if (reqAttr.find(localName) != reqAttr.end()) { + for (std::set<std::string>::const_iterator reqIter = reqAttr[localName].begin(); + reqIter != reqAttr[localName].end(); reqIter++) { + if (!HAS_ATTR(element, *reqIter)) { + issues.push_back(InterpreterIssue("Element " + localName + " is missing required attribute '" + *reqIter + "'", element, InterpreterIssue::USCXML_ISSUE_WARNING)); + } + if (HAS_ATTR(element, *reqIter) && ATTR(element, *reqIter).size() == 0) { + issues.push_back(InterpreterIssue("Required attribute '" + *reqIter + "' of element " + localName + " is empty", element, InterpreterIssue::USCXML_ISSUE_WARNING)); + } + } + } + + if (localName == "scxml") // can be anywhere: <assign>, <content>, <other:embed> + continue; + if (!element.getParentNode() || element.getParentNode().getNodeType() != Node_base::ELEMENT_NODE) { issues.push_back(InterpreterIssue("Parent of " + localName + " is no element", element, InterpreterIssue::USCXML_ISSUE_WARNING)); continue; @@ -649,123 +651,123 @@ NEXT_TRANSITION: } } - // check attribute constraints - { - for (int i = 0; i < initials.size(); i++) { - Element<std::string> initial = Element<std::string>(initials[i]); - if (initial.getParentNode() && initial.getParentNode().getNodeType() == Node_base::ELEMENT_NODE) { - Element<std::string> state(initial.getParentNode()); - if (HAS_ATTR(state, "initial")) { - issues.push_back(InterpreterIssue("State with initial attribute cannot have <initial> child ", state, InterpreterIssue::USCXML_ISSUE_WARNING)); - } - if (InterpreterImpl::isAtomic(state)) { - issues.push_back(InterpreterIssue("Atomic state cannot have <initial> child ", state, InterpreterIssue::USCXML_ISSUE_WARNING)); - } - } - } - for (int i = 0; i < allStates.size(); i++) { - Element<std::string> state = Element<std::string>(allStates[i]); - if (InterpreterImpl::isAtomic(state) && HAS_ATTR(state, "initial")) { - issues.push_back(InterpreterIssue("Atomic state cannot have initial attribute ", state, InterpreterIssue::USCXML_ISSUE_WARNING)); - } - } - - for (int i = 0; i < assigns.size(); i++) { - Element<std::string> assign = Element<std::string>(assigns[i]); - if (HAS_ATTR(assign, "expr") && assign.getChildNodes().getLength() > 0) { - issues.push_back(InterpreterIssue("Assign element cannot have expr attribute and children", assign, InterpreterIssue::USCXML_ISSUE_WARNING)); - } - } - - for (int i = 0; i < contents.size(); i++) { - Element<std::string> content = Element<std::string>(contents[i]); - if (HAS_ATTR(content, "expr") && content.getChildNodes().getLength() > 0) { - issues.push_back(InterpreterIssue("Content element cannot have expr attribute and children", content, InterpreterIssue::USCXML_ISSUE_WARNING)); - } - } - - for (int i = 0; i < params.size(); i++) { - Element<std::string> param = Element<std::string>(params[i]); - if (HAS_ATTR(param, "expr") && HAS_ATTR(param, "location")) { - issues.push_back(InterpreterIssue("Param element cannot have both expr and location attribute", param, InterpreterIssue::USCXML_ISSUE_WARNING)); - } - } - - for (int i = 0; i < scripts.size(); i++) { - Element<std::string> script = Element<std::string>(scripts[i]); - if (HAS_ATTR(script, "src") && script.getChildNodes().getLength() > 0) { - issues.push_back(InterpreterIssue("Script element cannot have src attribute and children", script, InterpreterIssue::USCXML_ISSUE_WARNING)); - } - } - - for (int i = 0; i < sends.size(); i++) { - Element<std::string> send = Element<std::string>(sends[i]); - if (HAS_ATTR(send, "event") && HAS_ATTR(send, "eventexpr")) { - issues.push_back(InterpreterIssue("Send element cannot have both event and eventexpr attribute", send, InterpreterIssue::USCXML_ISSUE_WARNING)); - } - if (HAS_ATTR(send, "target") && HAS_ATTR(send, "targetexpr")) { - issues.push_back(InterpreterIssue("Send element cannot have both target and targetexpr attribute", send, InterpreterIssue::USCXML_ISSUE_WARNING)); - } - if (HAS_ATTR(send, "type") && HAS_ATTR(send, "typeexpr")) { - issues.push_back(InterpreterIssue("Send element cannot have both type and typeexpr attribute", send, InterpreterIssue::USCXML_ISSUE_WARNING)); - } - if (HAS_ATTR(send, "id") && HAS_ATTR(send, "idlocation")) { - issues.push_back(InterpreterIssue("Send element cannot have both id and idlocation attribute", send, InterpreterIssue::USCXML_ISSUE_WARNING)); - } - if (HAS_ATTR(send, "delay") && HAS_ATTR(send, "delayexpr")) { - issues.push_back(InterpreterIssue("Send element cannot have both delay and delayexpr attribute", send, InterpreterIssue::USCXML_ISSUE_WARNING)); - } - if (HAS_ATTR(send, "delay") && HAS_ATTR(send, "target") && ATTR(send, "target")== "_internal") { - issues.push_back(InterpreterIssue("Send element cannot have delay with target _internal", send, InterpreterIssue::USCXML_ISSUE_WARNING)); - } - - NodeSet<std::string> contentChilds = InterpreterImpl::filterChildElements(_nsInfo.xmlNSPrefix + "content", send, false); - NodeSet<std::string> paramChilds = InterpreterImpl::filterChildElements(_nsInfo.xmlNSPrefix + "param", send, false); - - if (HAS_ATTR(send, "namelist") && contentChilds.size() > 0) { - issues.push_back(InterpreterIssue("Send element cannot have namelist attribute and content child", send, InterpreterIssue::USCXML_ISSUE_WARNING)); - } - - if (paramChilds.size() > 0 && contentChilds.size() > 0) { - issues.push_back(InterpreterIssue("Send element cannot have param child and content child", send, InterpreterIssue::USCXML_ISSUE_WARNING)); - } - - } - for (int i = 0; i < cancels.size(); i++) { - Element<std::string> cancel = Element<std::string>(cancels[i]); - if (HAS_ATTR(cancel, "sendid") && HAS_ATTR(cancel, "sendidexpr")) { - issues.push_back(InterpreterIssue("Cancel element cannot have both sendid and eventexpr sendidexpr", cancel, InterpreterIssue::USCXML_ISSUE_WARNING)); - } - } - - for (int i = 0; i < invokes.size(); i++) { - Element<std::string> invoke = Element<std::string>(invokes[i]); - if (HAS_ATTR(invoke, "type") && HAS_ATTR(invoke, "typeexpr")) { - issues.push_back(InterpreterIssue("Invoke element cannot have both type and typeexpr attribute", invoke, InterpreterIssue::USCXML_ISSUE_WARNING)); - } - if (HAS_ATTR(invoke, "src") && HAS_ATTR(invoke, "srcexpr")) { - issues.push_back(InterpreterIssue("Invoke element cannot have both src and srcexpr attribute", invoke, InterpreterIssue::USCXML_ISSUE_WARNING)); - } - if (HAS_ATTR(invoke, "id") && HAS_ATTR(invoke, "idlocation")) { - issues.push_back(InterpreterIssue("Invoke element cannot have both id and idlocation attribute", invoke, InterpreterIssue::USCXML_ISSUE_WARNING)); - } - if (HAS_ATTR(invoke, "namelist") && InterpreterImpl::filterChildElements(_nsInfo.xmlNSPrefix + "param", invoke, false).size() > 0) { - issues.push_back(InterpreterIssue("Invoke element cannot have namelist attribute and param child", invoke, InterpreterIssue::USCXML_ISSUE_WARNING)); - } - if (HAS_ATTR(invoke, "src") && InterpreterImpl::filterChildElements(_nsInfo.xmlNSPrefix + "content", invoke, false).size() > 0) { - issues.push_back(InterpreterIssue("Invoke element cannot have src attribute and content child", invoke, InterpreterIssue::USCXML_ISSUE_WARNING)); - - } - } - for (int i = 0; i < doneDatas.size(); i++) { - Element<std::string> donedata = Element<std::string>(doneDatas[i]); - if (InterpreterImpl::filterChildElements(_nsInfo.xmlNSPrefix + "content", donedata, false).size() > 0 && - InterpreterImpl::filterChildElements(_nsInfo.xmlNSPrefix + "param", donedata, false).size() > 0) { - issues.push_back(InterpreterIssue("Donedata element cannot have param child and content child", donedata, InterpreterIssue::USCXML_ISSUE_WARNING)); - - } - } - } + // check attribute constraints + { + for (int i = 0; i < initials.size(); i++) { + Element<std::string> initial = Element<std::string>(initials[i]); + if (initial.getParentNode() && initial.getParentNode().getNodeType() == Node_base::ELEMENT_NODE) { + Element<std::string> state(initial.getParentNode()); + if (HAS_ATTR(state, "initial")) { + issues.push_back(InterpreterIssue("State with initial attribute cannot have <initial> child ", state, InterpreterIssue::USCXML_ISSUE_WARNING)); + } + if (InterpreterImpl::isAtomic(state)) { + issues.push_back(InterpreterIssue("Atomic state cannot have <initial> child ", state, InterpreterIssue::USCXML_ISSUE_WARNING)); + } + } + } + for (int i = 0; i < allStates.size(); i++) { + Element<std::string> state = Element<std::string>(allStates[i]); + if (InterpreterImpl::isAtomic(state) && HAS_ATTR(state, "initial")) { + issues.push_back(InterpreterIssue("Atomic state cannot have initial attribute ", state, InterpreterIssue::USCXML_ISSUE_WARNING)); + } + } + + for (int i = 0; i < assigns.size(); i++) { + Element<std::string> assign = Element<std::string>(assigns[i]); + if (HAS_ATTR(assign, "expr") && assign.getChildNodes().getLength() > 0) { + issues.push_back(InterpreterIssue("Assign element cannot have expr attribute and children", assign, InterpreterIssue::USCXML_ISSUE_WARNING)); + } + } + + for (int i = 0; i < contents.size(); i++) { + Element<std::string> content = Element<std::string>(contents[i]); + if (HAS_ATTR(content, "expr") && content.getChildNodes().getLength() > 0) { + issues.push_back(InterpreterIssue("Content element cannot have expr attribute and children", content, InterpreterIssue::USCXML_ISSUE_WARNING)); + } + } + + for (int i = 0; i < params.size(); i++) { + Element<std::string> param = Element<std::string>(params[i]); + if (HAS_ATTR(param, "expr") && HAS_ATTR(param, "location")) { + issues.push_back(InterpreterIssue("Param element cannot have both expr and location attribute", param, InterpreterIssue::USCXML_ISSUE_WARNING)); + } + } + + for (int i = 0; i < scripts.size(); i++) { + Element<std::string> script = Element<std::string>(scripts[i]); + if (HAS_ATTR(script, "src") && script.getChildNodes().getLength() > 0) { + issues.push_back(InterpreterIssue("Script element cannot have src attribute and children", script, InterpreterIssue::USCXML_ISSUE_WARNING)); + } + } + + for (int i = 0; i < sends.size(); i++) { + Element<std::string> send = Element<std::string>(sends[i]); + if (HAS_ATTR(send, "event") && HAS_ATTR(send, "eventexpr")) { + issues.push_back(InterpreterIssue("Send element cannot have both event and eventexpr attribute", send, InterpreterIssue::USCXML_ISSUE_WARNING)); + } + if (HAS_ATTR(send, "target") && HAS_ATTR(send, "targetexpr")) { + issues.push_back(InterpreterIssue("Send element cannot have both target and targetexpr attribute", send, InterpreterIssue::USCXML_ISSUE_WARNING)); + } + if (HAS_ATTR(send, "type") && HAS_ATTR(send, "typeexpr")) { + issues.push_back(InterpreterIssue("Send element cannot have both type and typeexpr attribute", send, InterpreterIssue::USCXML_ISSUE_WARNING)); + } + if (HAS_ATTR(send, "id") && HAS_ATTR(send, "idlocation")) { + issues.push_back(InterpreterIssue("Send element cannot have both id and idlocation attribute", send, InterpreterIssue::USCXML_ISSUE_WARNING)); + } + if (HAS_ATTR(send, "delay") && HAS_ATTR(send, "delayexpr")) { + issues.push_back(InterpreterIssue("Send element cannot have both delay and delayexpr attribute", send, InterpreterIssue::USCXML_ISSUE_WARNING)); + } + if (HAS_ATTR(send, "delay") && HAS_ATTR(send, "target") && ATTR(send, "target")== "_internal") { + issues.push_back(InterpreterIssue("Send element cannot have delay with target _internal", send, InterpreterIssue::USCXML_ISSUE_WARNING)); + } + + NodeSet<std::string> contentChilds = InterpreterImpl::filterChildElements(_nsInfo.xmlNSPrefix + "content", send, false); + NodeSet<std::string> paramChilds = InterpreterImpl::filterChildElements(_nsInfo.xmlNSPrefix + "param", send, false); + + if (HAS_ATTR(send, "namelist") && contentChilds.size() > 0) { + issues.push_back(InterpreterIssue("Send element cannot have namelist attribute and content child", send, InterpreterIssue::USCXML_ISSUE_WARNING)); + } + + if (paramChilds.size() > 0 && contentChilds.size() > 0) { + issues.push_back(InterpreterIssue("Send element cannot have param child and content child", send, InterpreterIssue::USCXML_ISSUE_WARNING)); + } + + } + for (int i = 0; i < cancels.size(); i++) { + Element<std::string> cancel = Element<std::string>(cancels[i]); + if (HAS_ATTR(cancel, "sendid") && HAS_ATTR(cancel, "sendidexpr")) { + issues.push_back(InterpreterIssue("Cancel element cannot have both sendid and eventexpr sendidexpr", cancel, InterpreterIssue::USCXML_ISSUE_WARNING)); + } + } + + for (int i = 0; i < invokes.size(); i++) { + Element<std::string> invoke = Element<std::string>(invokes[i]); + if (HAS_ATTR(invoke, "type") && HAS_ATTR(invoke, "typeexpr")) { + issues.push_back(InterpreterIssue("Invoke element cannot have both type and typeexpr attribute", invoke, InterpreterIssue::USCXML_ISSUE_WARNING)); + } + if (HAS_ATTR(invoke, "src") && HAS_ATTR(invoke, "srcexpr")) { + issues.push_back(InterpreterIssue("Invoke element cannot have both src and srcexpr attribute", invoke, InterpreterIssue::USCXML_ISSUE_WARNING)); + } + if (HAS_ATTR(invoke, "id") && HAS_ATTR(invoke, "idlocation")) { + issues.push_back(InterpreterIssue("Invoke element cannot have both id and idlocation attribute", invoke, InterpreterIssue::USCXML_ISSUE_WARNING)); + } + if (HAS_ATTR(invoke, "namelist") && InterpreterImpl::filterChildElements(_nsInfo.xmlNSPrefix + "param", invoke, false).size() > 0) { + issues.push_back(InterpreterIssue("Invoke element cannot have namelist attribute and param child", invoke, InterpreterIssue::USCXML_ISSUE_WARNING)); + } + if (HAS_ATTR(invoke, "src") && InterpreterImpl::filterChildElements(_nsInfo.xmlNSPrefix + "content", invoke, false).size() > 0) { + issues.push_back(InterpreterIssue("Invoke element cannot have src attribute and content child", invoke, InterpreterIssue::USCXML_ISSUE_WARNING)); + + } + } + for (int i = 0; i < doneDatas.size(); i++) { + Element<std::string> donedata = Element<std::string>(doneDatas[i]); + if (InterpreterImpl::filterChildElements(_nsInfo.xmlNSPrefix + "content", donedata, false).size() > 0 && + InterpreterImpl::filterChildElements(_nsInfo.xmlNSPrefix + "param", donedata, false).size() > 0) { + issues.push_back(InterpreterIssue("Donedata element cannot have param child and content child", donedata, InterpreterIssue::USCXML_ISSUE_WARNING)); + + } + } + } // check that the datamodel is known if not already instantiated if (!interpreter->_dataModel) { diff --git a/src/uscxml/debug/InterpreterIssue.h b/src/uscxml/debug/InterpreterIssue.h index 0e1f949..5959d07 100644 --- a/src/uscxml/debug/InterpreterIssue.h +++ b/src/uscxml/debug/InterpreterIssue.h @@ -36,13 +36,13 @@ public: USCXML_ISSUE_INFO }; - InterpreterIssue(const std::string& msg, Arabica::DOM::Node<std::string> node, IssueSeverity severity, const std::string& specRef = ""); + InterpreterIssue(const std::string& msg, Arabica::DOM::Node<std::string> node, IssueSeverity severity, const std::string& specRef = ""); std::string xPath; - std::string message; + std::string message; Arabica::DOM::Node<std::string> node; IssueSeverity severity; - std::string specRef; + std::string specRef; private: static std::list<InterpreterIssue> forInterpreter(InterpreterImpl* interpreter); diff --git a/src/uscxml/interpreter/InterpreterDraft6.cpp b/src/uscxml/interpreter/InterpreterDraft6.cpp index 48ba78f..f79049d 100644 --- a/src/uscxml/interpreter/InterpreterDraft6.cpp +++ b/src/uscxml/interpreter/InterpreterDraft6.cpp @@ -441,13 +441,13 @@ void InterpreterDraft6::enterStates(const Arabica::XPath::NodeSet<std::string>& } #endif if (isFinal(stateElem)) { - - Arabica::DOM::Element<std::string> doneData; - Arabica::XPath::NodeSet<std::string> doneDatas = filterChildElements(_nsInfo.xmlNSPrefix + "donedata", stateElem); - if (doneDatas.size() > 0) { - // only process first donedata element - doneData = Element<std::string>(doneDatas[0]); - } + + Arabica::DOM::Element<std::string> doneData; + Arabica::XPath::NodeSet<std::string> doneDatas = filterChildElements(_nsInfo.xmlNSPrefix + "donedata", stateElem); + if (doneDatas.size() > 0) { + // only process first donedata element + doneData = Element<std::string>(doneDatas[0]); + } internalDoneSend(stateElem, doneData); Node<std::string> parent = stateElem.getParentNode(); diff --git a/src/uscxml/interpreter/InterpreterRC.cpp b/src/uscxml/interpreter/InterpreterRC.cpp index 879c771..e1f4ada 100644 --- a/src/uscxml/interpreter/InterpreterRC.cpp +++ b/src/uscxml/interpreter/InterpreterRC.cpp @@ -181,7 +181,7 @@ function computeExitSet(transitions) return statesToExit */ Arabica::XPath::NodeSet<std::string> InterpreterRC::computeExitSet(const Arabica::XPath::NodeSet<std::string>& transitions) { - + NodeSet<std::string> statesToExit; for (unsigned int i = 0; i < transitions.size(); i++) { Element<std::string> t(transitions[i]); @@ -204,7 +204,7 @@ Arabica::XPath::NodeSet<std::string> InterpreterRC::computeExitSet(const Arabica } std::cout << std::endl; #endif - + return statesToExit; } @@ -214,16 +214,16 @@ Arabica::XPath::NodeSet<std::string> InterpreterRC::computeExitSet(const Arabica Arabica::XPath::NodeSet<std::string> transitions; transitions.push_back(transition); - + Arabica::XPath::NodeSet<std::string> exitSet = computeExitSet(transitions); //_exitSet[transition] = exitSet; - + #if 0 - std::cerr << "Exit set for transition '" << transition << "': " << std::endl; - for (int i = 0; i < exitSet.size(); i++) { - std::cerr << ATTR_CAST(exitSet[i], "id") << std::endl << "----" << std::endl; - } - std::cerr << std::endl; + std::cerr << "Exit set for transition '" << transition << "': " << std::endl; + for (int i = 0; i < exitSet.size(); i++) { + std::cerr << ATTR_CAST(exitSet[i], "id") << std::endl << "----" << std::endl; + } + std::cerr << std::endl; #endif return exitSet; } @@ -302,19 +302,19 @@ void InterpreterRC::enterStates(const Arabica::XPath::NodeSet<std::string>& enab } if (isFinal(s)) { - Element<std::string> parent = (Element<std::string>)s.getParentNode(); + Element<std::string> parent = (Element<std::string>)s.getParentNode(); - Arabica::DOM::Element<std::string> doneData; - Arabica::XPath::NodeSet<std::string> doneDatas = filterChildElements(_nsInfo.xmlNSPrefix + "donedata", s); - if (doneDatas.size() > 0) { - // only process first donedata element - doneData = Element<std::string>(doneDatas[0]); - } + Arabica::DOM::Element<std::string> doneData; + Arabica::XPath::NodeSet<std::string> doneDatas = filterChildElements(_nsInfo.xmlNSPrefix + "donedata", s); + if (doneDatas.size() > 0) { + // only process first donedata element + doneData = Element<std::string>(doneDatas[0]); + } - if (parentIsScxmlState(s)) { + if (parentIsScxmlState(s)) { _topLevelFinalReached = true; } else { - internalDoneSend(parent, doneData); + internalDoneSend(parent, doneData); Element<std::string> grandParent = (Element<std::string>)parent.getParentNode(); // internalDoneSend(parent, Arabica::DOM::Element<std::string>()); @@ -648,7 +648,7 @@ BREAK_LOOP: void InterpreterRC::handleDOMEvent(Arabica::DOM::Events::Event<std::string>& event) { InterpreterImpl::handleDOMEvent(event); - + if (event.getType().compare("DOMAttrModified") == 0) // we do not care about attributes return; @@ -656,6 +656,6 @@ void InterpreterRC::handleDOMEvent(Arabica::DOM::Events::Event<std::string>& eve // NodeSet<std::string> transitions = InterpreterImpl::filterChildElements(_nsInfo.xmlNSPrefix + "transition", target, true); // if (transitions.size() > 0) _exitSet.clear(); - + } }
\ No newline at end of file diff --git a/src/uscxml/messages/InvokeRequest.h b/src/uscxml/messages/InvokeRequest.h index 7cecf8d..6f597fe 100644 --- a/src/uscxml/messages/InvokeRequest.h +++ b/src/uscxml/messages/InvokeRequest.h @@ -61,7 +61,7 @@ protected: std::string src; bool autoForward; Arabica::DOM::Element<std::string> elem; - + friend USCXML_API std::ostream& operator<< (std::ostream& os, const InvokeRequest& sendReq); }; diff --git a/src/uscxml/plugins/DataModel.h b/src/uscxml/plugins/DataModel.h index 74277c8..df0143d 100644 --- a/src/uscxml/plugins/DataModel.h +++ b/src/uscxml/plugins/DataModel.h @@ -116,7 +116,7 @@ protected: class USCXML_API DataModel { public: - + DataModel() : _impl() {} DataModel(const boost::shared_ptr<DataModelImpl> impl) : _impl(impl) { } DataModel(const DataModel& other) : _impl(other._impl) { } @@ -140,121 +140,121 @@ public: } virtual std::list<std::string> getNames() { - TIME_BLOCK - return _impl->getNames(); + TIME_BLOCK + return _impl->getNames(); } virtual bool validate(const std::string& location, const std::string& schema) { - TIME_BLOCK + TIME_BLOCK return _impl->validate(location, schema); } virtual bool isLocation(const std::string& expr) { - TIME_BLOCK + TIME_BLOCK return _impl->isLocation(expr); } virtual bool isValidSyntax(const std::string& expr) { - TIME_BLOCK + TIME_BLOCK return _impl->isValidSyntax(expr); } virtual void setEvent(const Event& event) { - TIME_BLOCK + TIME_BLOCK return _impl->setEvent(event); } virtual Data getStringAsData(const std::string& content) { - TIME_BLOCK + TIME_BLOCK return _impl->getStringAsData(content); } virtual void pushContext() { - TIME_BLOCK + TIME_BLOCK return _impl->pushContext(); } virtual void popContext() { - TIME_BLOCK + TIME_BLOCK return _impl->popContext(); } virtual void eval(const Arabica::DOM::Element<std::string>& scriptElem, const std::string& expr) { - TIME_BLOCK + TIME_BLOCK return _impl->eval(scriptElem, expr); } virtual std::string evalAsString(const std::string& expr) { - TIME_BLOCK + TIME_BLOCK return _impl->evalAsString(expr); } virtual bool evalAsBool(const std::string& expr) { - TIME_BLOCK + TIME_BLOCK return _impl->evalAsBool(expr); } virtual bool evalAsBool(const Arabica::DOM::Element<std::string>& scriptNode, const std::string& expr) { - TIME_BLOCK + TIME_BLOCK return _impl->evalAsBool(scriptNode, expr); } virtual uint32_t getLength(const std::string& expr) { - TIME_BLOCK + TIME_BLOCK return _impl->getLength(expr); } virtual void setForeach(const std::string& item, const std::string& array, const std::string& index, uint32_t iteration) { - TIME_BLOCK + TIME_BLOCK return _impl->setForeach(item, array, index, iteration); } virtual void assign(const Arabica::DOM::Element<std::string>& assignElem, const Arabica::DOM::Node<std::string>& node, const std::string& content) { - TIME_BLOCK + TIME_BLOCK return _impl->assign(assignElem, node, content); } virtual void assign(const std::string& location, const Data& data) { - TIME_BLOCK + TIME_BLOCK return _impl->assign(location, data); } virtual void init(const Arabica::DOM::Element<std::string>& dataElem, const Arabica::DOM::Node<std::string>& node, const std::string& content) { - TIME_BLOCK + TIME_BLOCK return _impl->init(dataElem, node, content); } virtual void init(const std::string& location, const Data& data) { - TIME_BLOCK + TIME_BLOCK return _impl->init(location, data); } virtual bool isDeclared(const std::string& expr) { - TIME_BLOCK + TIME_BLOCK return _impl->isDeclared(expr); } size_t replaceExpressions(std::string& content) { - TIME_BLOCK + TIME_BLOCK return _impl->replaceExpressions(content); } std::string andExpressions(std::list<std::string> expressions) { - TIME_BLOCK + TIME_BLOCK return _impl->andExpressions(expressions); } virtual void setInterpreter(InterpreterInfo* interpreter) { - TIME_BLOCK + TIME_BLOCK _impl->setInterpreter(interpreter); } virtual void addExtension(DataModelExtension* ext) { - TIME_BLOCK + TIME_BLOCK _impl->addExtension(ext); } - + #ifdef BUILD_PROFILING - Timer timer; + Timer timer; #endif protected: diff --git a/src/uscxml/plugins/datamodel/ecmascript/JavaScriptCore/JSCDataModel.cpp b/src/uscxml/plugins/datamodel/ecmascript/JavaScriptCore/JSCDataModel.cpp index 40b6cc2..fd4da3c 100644 --- a/src/uscxml/plugins/datamodel/ecmascript/JavaScriptCore/JSCDataModel.cpp +++ b/src/uscxml/plugins/datamodel/ecmascript/JavaScriptCore/JSCDataModel.cpp @@ -89,10 +89,10 @@ JSCDataModel::~JSCDataModel() { void JSCDataModel::addExtension(DataModelExtension* ext) { if (_extensions.find(ext) != _extensions.end()) return; - + ext->dm = this; _extensions.insert(ext); - + JSObjectRef currScope = JSContextGetGlobalObject(_ctx); std::list<std::string> locPath = InterpreterImpl::tokenize(ext->provides(), '.'); std::list<std::string>::iterator locIter = locPath.begin(); @@ -108,7 +108,7 @@ void JSCDataModel::addExtension(DataModelExtension* ext) { JSValueRef newScope = JSObjectGetProperty(_ctx, currScope, pathCompJS, NULL); JSStringRelease(pathCompJS); - + if (JSValueIsObject(_ctx, newScope)) { currScope = JSValueToObject(_ctx, newScope, NULL); } else { @@ -129,10 +129,10 @@ void JSCDataModel::addExtension(DataModelExtension* ext) { JSValueRef JSCDataModel::jsExtension(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) { DataModelExtension* extension = (DataModelExtension*)JSObjectGetPrivate(function); - + JSStringRef memberRef; std::string memberName; - + if (argumentCount > 0 && JSValueIsString(ctx, arguments[0])) { memberRef = JSValueToStringCopy(ctx, arguments[0], exception); size_t maxSize = JSStringGetMaximumUTF8CStringSize(memberRef); @@ -192,16 +192,16 @@ JSClassDefinition JSCDataModel::jsInvokersClassDef = { 0, 0, "invokers", 0, 0, 0 boost::shared_ptr<DataModelImpl> JSCDataModel::create(InterpreterInfo* interpreter) { boost::shared_ptr<JSCDataModel> dm = boost::shared_ptr<JSCDataModel>(new JSCDataModel()); - + dm->_ctx = JSGlobalContextCreate(NULL); dm->_interpreter = interpreter; - dm->_dom = new JSCDOM(); - dm->_dom->xpath = new XPath<std::string>(); - dm->_dom->xpath->setNamespaceContext(*interpreter->getNameSpaceInfo().getNSContext()); - dm->_dom->storage = new Storage(URL::getResourceDir() + PATH_SEPERATOR + interpreter->getName() + ".storage"); - dm->_dom->nsInfo = new NameSpaceInfo(interpreter->getNameSpaceInfo()); - + dm->_dom = new JSCDOM(); + dm->_dom->xpath = new XPath<std::string>(); + dm->_dom->xpath->setNamespaceContext(*interpreter->getNameSpaceInfo().getNSContext()); + dm->_dom->storage = new Storage(URL::getResourceDir() + PATH_SEPERATOR + interpreter->getName() + ".storage"); + dm->_dom->nsInfo = new NameSpaceInfo(interpreter->getNameSpaceInfo()); + // introduce global functions as objects for private data JSClassRef jsInClassRef = JSClassCreate(&jsInClassDef); JSObjectRef jsIn = JSObjectMake(dm->_ctx, jsInClassRef, dm.get()); diff --git a/src/uscxml/plugins/datamodel/ecmascript/JavaScriptCore/JSCDataModel.h b/src/uscxml/plugins/datamodel/ecmascript/JavaScriptCore/JSCDataModel.h index 9bc39d6..2a2b1cc 100644 --- a/src/uscxml/plugins/datamodel/ecmascript/JavaScriptCore/JSCDataModel.h +++ b/src/uscxml/plugins/datamodel/ecmascript/JavaScriptCore/JSCDataModel.h @@ -105,7 +105,7 @@ protected: static bool jsInvokerHasProp(JSContextRef ctx, JSObjectRef object, JSStringRef propertyName); static JSValueRef jsInvokerGetProp(JSContextRef ctx, JSObjectRef object, JSStringRef propertyName, JSValueRef* exception); static void jsInvokerListProps(JSContextRef ctx, JSObjectRef object, JSPropertyNameAccumulatorRef propertyNames); - + JSValueRef getNodeAsValue(const Arabica::DOM::Node<std::string>& node); JSValueRef getDataAsValue(const Data& data); Data getValueAsData(const JSValueRef value); @@ -117,10 +117,10 @@ protected: std::string _name; std::set<DataModelExtension*> _extensions; - + Event _event; JSGlobalContextRef _ctx; - + }; #ifdef BUILD_AS_PLUGINS diff --git a/src/uscxml/plugins/datamodel/ecmascript/v8/V8DataModel.cpp b/src/uscxml/plugins/datamodel/ecmascript/v8/V8DataModel.cpp index 99df4a7..3004b91 100644 --- a/src/uscxml/plugins/datamodel/ecmascript/v8/V8DataModel.cpp +++ b/src/uscxml/plugins/datamodel/ecmascript/v8/V8DataModel.cpp @@ -93,7 +93,7 @@ V8DataModel::~V8DataModel() { void V8DataModel::addExtension(DataModelExtension* ext) { if (_extensions.find(ext) != _extensions.end()) return; - + ext->dm = this; _extensions.insert(ext); @@ -107,13 +107,13 @@ void V8DataModel::addExtension(DataModelExtension* ext) { while(true) { std::string pathComp = *locIter; v8::Local<v8::String> pathCompJS = v8::String::New(locIter->c_str()); - + if (++locIter != locPath.end()) { // just another intermediate step if (!currScope->Has(pathCompJS)) { currScope->Set(pathCompJS, v8::Object::New()); } - + v8::Local<v8::Value> newScope = currScope->Get(pathCompJS); if (newScope->IsObject()) { currScope = newScope->ToObject(); @@ -133,19 +133,19 @@ v8::Handle<v8::Value> V8DataModel::jsExtension(const v8::Arguments& args) { v8::Local<v8::String> memberJS; std::string memberName; - + if (args.Length() > 0 && args[0]->IsString()) { memberJS = args[0]->ToString(); memberName = *v8::String::AsciiValue(memberJS); } - + if (args.Length() > 1) { // setter Data data = ((V8DataModel*)(extension->dm))->getValueAsData(args[1]); extension->setValueOf(memberName, data); return v8::Undefined(); } - + if (args.Length() == 1) { // getter return ((V8DataModel*)(extension->dm))->getDataAsValue(extension->getValueOf(memberName)); diff --git a/src/uscxml/plugins/datamodel/prolog/swi/SWIDataModel.cpp b/src/uscxml/plugins/datamodel/prolog/swi/SWIDataModel.cpp index 09b5e15..fc41901 100644 --- a/src/uscxml/plugins/datamodel/prolog/swi/SWIDataModel.cpp +++ b/src/uscxml/plugins/datamodel/prolog/swi/SWIDataModel.cpp @@ -689,9 +689,9 @@ bool SWIDataModel::evalAsBool(const Arabica::DOM::Element<std::string>& node, co } PlQuery query(compound.name(), termv); return query.next_solution() > 0; - } - RETHROW_PLEX_AS_EVENT - catch(...) { + } + RETHROW_PLEX_AS_EVENT + catch(...) { return false; } } diff --git a/src/uscxml/plugins/datamodel/promela/PromelaDataModel.cpp b/src/uscxml/plugins/datamodel/promela/PromelaDataModel.cpp index 6e82b55..cd6bef3 100644 --- a/src/uscxml/plugins/datamodel/promela/PromelaDataModel.cpp +++ b/src/uscxml/plugins/datamodel/promela/PromelaDataModel.cpp @@ -310,7 +310,7 @@ void PromelaDataModel::assign(const Element<std::string>& assignElem, if (value.length() == 0) return; - + Data json = Data::fromJSON(value); if (!json.empty()) { // simply assign from json to key @@ -371,7 +371,7 @@ void PromelaDataModel::evaluateDecl(void* ast) { std::list<PromelaParserNode*>::iterator opIterAsgn = (*nameIter)->operands.begin(); PromelaParserNode* name = *opIterAsgn++; PromelaParserNode* expr = *opIterAsgn++; - + try { variable.compound["value"] = evaluateExpr(expr); } catch(uscxml::Event e) { @@ -562,7 +562,7 @@ void PromelaDataModel::evaluateStmnt(void* ast) { } } - + void PromelaDataModel::setVariable(void* ast, const Data& value) { PromelaParserNode* node = (PromelaParserNode*)ast; @@ -602,7 +602,7 @@ void PromelaDataModel::setVariable(void* ast, const Data& value) { 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<size_t>(_variables[node->value].compound["size"].atom) < value.array.size()) ERROR_EXECUTION_THROW("Array assigned to " + node->value + " is too large"); } @@ -620,28 +620,29 @@ void PromelaDataModel::setVariable(void* ast, const Data& value) { } // 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++; + 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"); + 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(); @@ -767,11 +768,11 @@ void PromelaDataModel::init(const Element<std::string>& dataElem, arrSize = type.substr(bracketPos, type.length() - bracketPos); type = type.substr(0, bracketPos); } - + std::string expr = type + " " + identifier + arrSize; PromelaParser parser(expr, 1, PromelaParser::PROMELA_DECL); evaluateDecl(parser.ast); - + } assign(dataElem, node, content); } @@ -789,9 +790,10 @@ bool PromelaDataModel::isDeclared(const std::string& expr) { // JSON declaration std::list<PromelaParserNode*>::iterator opIter = parser.ast->operands.begin(); Data* var = &_variables; - + while(opIter != parser.ast->operands.end()) { - std::string name = (*opIter)->value; opIter++; + 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()) { @@ -801,7 +803,7 @@ bool PromelaDataModel::isDeclared(const std::string& expr) { } } return true; - + } return _variables.compound.find(expr) != _variables.compound.end(); diff --git a/src/uscxml/plugins/datamodel/promela/PromelaParser.cpp b/src/uscxml/plugins/datamodel/promela/PromelaParser.cpp index 74cb791..c07fca2 100644 --- a/src/uscxml/plugins/datamodel/promela/PromelaParser.cpp +++ b/src/uscxml/plugins/datamodel/promela/PromelaParser.cpp @@ -136,7 +136,7 @@ PromelaParserNode::~PromelaParserNode() { PromelaParserNode* PromelaParser::node(int type, int nrArgs, ...) { PromelaParserNode* newNode = new PromelaParserNode(); - + newNode->type = type; va_list ap; va_start(ap, nrArgs); @@ -164,7 +164,7 @@ PromelaParserNode* PromelaParser::value(int type, void* location, const char* va return newNode; } - + void PromelaParser::dump() { switch (type) { case PROMELA_EXPR: diff --git a/src/uscxml/plugins/datamodel/promela/PromelaParser.h b/src/uscxml/plugins/datamodel/promela/PromelaParser.h index d1683b9..d79a2d0 100644 --- a/src/uscxml/plugins/datamodel/promela/PromelaParser.h +++ b/src/uscxml/plugins/datamodel/promela/PromelaParser.h @@ -40,7 +40,7 @@ public: int lastLine; int lastCol; }; - + PromelaParserNode() : type(0), parent(NULL), loc(NULL) {} virtual ~PromelaParserNode(); @@ -85,7 +85,7 @@ public: operator bool() const { return ast != NULL; } - + protected: void init(const std::string& expr); diff --git a/src/uscxml/plugins/datamodel/promela/parser/promela.lex.yy.cpp b/src/uscxml/plugins/datamodel/promela/parser/promela.lex.yy.cpp index 2cd66f2..50e9776 100644 --- a/src/uscxml/plugins/datamodel/promela/parser/promela.lex.yy.cpp +++ b/src/uscxml/plugins/datamodel/promela/parser/promela.lex.yy.cpp @@ -26,7 +26,7 @@ /* %endif */ /* %if-c-only */ - + /* %endif */ /* %if-c-only */ @@ -58,7 +58,7 @@ #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. + * if you want the limit (max/min) macros for int types. */ #ifndef __STDC_LIMIT_MACROS #define __STDC_LIMIT_MACROS 1 @@ -76,7 +76,7 @@ typedef uint64_t flex_uint64_t; 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 char flex_uint8_t; typedef unsigned short int flex_uint16_t; typedef unsigned int flex_uint32_t; #endif /* ! C99 */ @@ -230,21 +230,21 @@ typedef size_t yy_size_t; #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) \ +/* 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 \ @@ -263,14 +263,13 @@ typedef size_t yy_size_t; #ifndef YY_STRUCT_YY_BUFFER_STATE #define YY_STRUCT_YY_BUFFER_STATE -struct yy_buffer_state - { -/* %if-c-only */ +struct yy_buffer_state { + /* %if-c-only */ FILE *yy_input_file; -/* %endif */ + /* %endif */ -/* %if-c++-only */ -/* %endif */ + /* %if-c++-only */ + /* %endif */ char *yy_ch_buf; /* input buffer */ char *yy_buf_pos; /* current position in input buffer */ @@ -304,9 +303,9 @@ struct yy_buffer_state */ int yy_at_bol; - int yy_bs_lineno; /**< The line count. */ - int yy_bs_column; /**< The column count. */ - + 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. */ @@ -328,7 +327,7 @@ struct yy_buffer_state */ #define YY_BUFFER_EOF_PENDING 2 - }; +}; #endif /* !YY_STRUCT_YY_BUFFER_STATE */ /* %if-c-only Standard (non-C++) definition */ @@ -451,179 +450,179 @@ static void yy_fatal_error (yyconst char msg[] ,yyscan_t yyscanner ); #define YY_END_OF_BUFFER 47 /* This struct is not used in this scanner, but its presence is necessary. */ -struct yy_trans_info - { +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 - } ; +}; +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 - } ; +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. @@ -637,7 +636,7 @@ static yyconst flex_int16_t yy_rule_linenum[46] = /* 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 @@ -645,7 +644,7 @@ static yyconst flex_int16_t yy_rule_linenum[46] = #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 \ @@ -681,42 +680,41 @@ static yyconst flex_int16_t yy_rule_linenum[46] = /* %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 */ +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 */ @@ -726,12 +724,12 @@ static int yy_init_globals (yyscan_t yyscanner ); /* %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 - +/* 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); @@ -775,10 +773,10 @@ 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 ); - +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 @@ -795,8 +793,8 @@ extern int promela_wrap (yyscan_t yyscanner ); /* %not-for-header */ - static void yyunput (int c,char *buf_ptr ,yyscan_t yyscanner); - +static void yyunput (int c,char *buf_ptr ,yyscan_t yyscanner); + /* %ok-for-header */ /* %endif */ @@ -926,7 +924,7 @@ static int input (yyscan_t yyscanner ); /* %if-c-only Standard (non-C++) definition */ extern int promela_lex \ - (YYSTYPE * yylval_param,YYLTYPE * yylloc_param ,yyscan_t yyscanner); +(YYSTYPE * yylval_param,YYLTYPE * yylloc_param ,yyscan_t yyscanner); #define YY_DECL int promela_lex \ (YYSTYPE * yylval_param, YYLTYPE * yylloc_param , yyscan_t yyscanner) @@ -955,25 +953,23 @@ extern int promela_lex \ /** The main scanner function which does all the work. */ -YY_DECL -{ +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; + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; -/* %% [7.0] user's declarations go here */ + /* %% [7.0] user's declarations go here */ #line 42 "promela.l" #line 970 "promela.lex.yy.cpp" - yylval = yylval_param; + yylval = yylval_param; - yylloc = yylloc_param; + yylloc = yylloc_param; - if ( !yyg->yy_init ) - { + if ( !yyg->yy_init ) { yyg->yy_init = 1; #ifdef YY_USER_INIT @@ -984,31 +980,30 @@ YY_DECL yyg->yy_start = 1; /* first start state */ if ( ! yyin ) -/* %if-c-only */ + /* %if-c-only */ yyin = stdin; -/* %endif */ -/* %if-c++-only */ -/* %endif */ + /* %endif */ + /* %if-c++-only */ + /* %endif */ if ( ! yyout ) -/* %if-c-only */ + /* %if-c-only */ yyout = stdout; -/* %endif */ -/* %if-c++-only */ -/* %endif */ + /* %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__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 */ + 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. */ @@ -1019,55 +1014,50 @@ YY_DECL */ yy_bp = yy_cp; -/* %% [9.0] code to set up and find next match goes here */ + /* %% [9.0] code to set up and find next match goes here */ yy_current_state = yyg->yy_start; yy_match: - do - { + do { register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)]; - if ( yy_accept[yy_current_state] ) - { + 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 ) - { + } + 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 ); + } 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 */ + /* %% [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 */ + /* %% [11.0] code for yylineno update goes here */ - if ( yy_act != YY_END_OF_BUFFER && yy_rule_can_match_eol[yy_act] ) - { + 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 { + 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 ) - { + /* %% [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 ) @@ -1080,391 +1070,384 @@ do_action: /* This label is used only to access EOF actions. */ 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 */ + 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 + case 1: + /* rule 1 can match eol */ + YY_RULE_SETUP #line 44 "promela.l" -/* multiline comments */ - YY_BREAK -case 2: -YY_RULE_SETUP + /* 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 + { + 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 + { + /* 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 + /* 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 + 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; + case YY_STATE_EOF(INITIAL): + yyterminate(); - /* Undo the effects of YY_DO_BEFORE_ACTION. */ - *yy_cp = yyg->yy_hold_char; - YY_RESTORE_YY_MORE_OFFSET + 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; - 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; + /* 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; + /* 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; + yyg->yy_c_buf_p = yyg->yytext_ptr + yy_amount_of_matched_text; - yy_current_state = yy_get_previous_state( yyscanner ); + 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). - */ + /* 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_next_state = yy_try_NUL_trans( yy_current_state , yyscanner); - yy_bp = yyg->yytext_ptr + YY_MORE_ADJ; + 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; + 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 { + /* %% [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 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; + else { + if ( ! yyg->yy_did_buffer_switch_on_eof ) + YY_NEW_FILE; } - break; + break; } - case EOB_ACT_CONTINUE_SCAN: - yyg->yy_c_buf_p = - yyg->yytext_ptr + yy_amount_of_matched_text; + 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_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; + 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]; + 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_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; + 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 */ + 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 */ @@ -1488,7 +1471,7 @@ static int yy_get_next_buffer (yyscan_t yyscanner) /* %if-c++-only */ /* %endif */ { - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + 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; @@ -1496,26 +1479,24 @@ static int yy_get_next_buffer (yyscan_t yyscanner) 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" ); + "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 ) - { + 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 - { + else { /* We matched some text prior to the EOB, first * process it. */ return EOB_ACT_LAST_MATCH; - } } + } /* Try to read more data. */ @@ -1531,22 +1512,20 @@ static int yy_get_next_buffer (yyscan_t yyscanner) */ 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; + 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. */ + 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); + (int) (yyg->yy_c_buf_p - b->yy_ch_buf); - if ( b->yy_is_our_buffer ) - { + if ( b->yy_is_our_buffer ) { yy_size_t new_size = b->yy_buf_size * 2; if ( new_size <= 0 ) @@ -1555,49 +1534,45 @@ static int yy_get_next_buffer (yyscan_t yyscanner) 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 + /* 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" ); + "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; + 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 ); + 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 ) - { + 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 - { + else { ret_val = EOB_ACT_LAST_MATCH; YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = - YY_BUFFER_EOF_PENDING; - } + YY_BUFFER_EOF_PENDING; } + } else ret_val = EOB_ACT_CONTINUE_SCAN; @@ -1624,35 +1599,32 @@ static int yy_get_next_buffer (yyscan_t yyscanner) /* %if-c-only */ /* %not-for-header */ - static yy_state_type yy_get_previous_state (yyscan_t yyscanner) +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; + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; -/* %% [15.0] code to get the start state into yy_current_state goes here */ + /* %% [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 */ + 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] ) - { + 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 ) - { + } + 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_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; + } return yy_current_state; } @@ -1663,28 +1635,26 @@ static int yy_get_next_buffer (yyscan_t yyscanner) * 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) +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 */ + 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] ) - { + 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 ) - { + } + 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); @@ -1693,27 +1663,27 @@ static int yy_get_next_buffer (yyscan_t yyscanner) /* %if-c-only */ - static void yyunput (int c, register char * yy_bp , yyscan_t yyscanner) +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; + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - yy_cp = yyg->yy_c_buf_p; + 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 */ + 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]; + YY_CURRENT_BUFFER_LVALUE->yy_buf_size + 2]; register char *source = - &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]; + &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]; while ( source > YY_CURRENT_BUFFER_LVALUE->yy_ch_buf ) *--dest = *--source; @@ -1721,19 +1691,19 @@ static int yy_get_next_buffer (yyscan_t yyscanner) 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; + 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 */ + /* %% [18.0] update yylineno here */ - if ( c == '\n' ){ - --yylineno; - } + if ( c == '\n' ) { + --yylineno; + } yyg->yytext_ptr = yy_bp; yyg->yy_hold_char = *yy_cp; @@ -1746,9 +1716,9 @@ static int yy_get_next_buffer (yyscan_t yyscanner) /* %if-c-only */ #ifndef YY_NO_INPUT #ifdef __cplusplus - static int yyinput (yyscan_t yyscanner) +static int yyinput (yyscan_t yyscanner) #else - static int input (yyscan_t yyscanner) +static int input (yyscan_t yyscanner) #endif /* %endif */ @@ -1756,12 +1726,11 @@ static int yy_get_next_buffer (yyscan_t yyscanner) /* %endif */ { int c; - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + 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 ) - { + 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. @@ -1770,61 +1739,60 @@ static int yy_get_next_buffer (yyscan_t yyscanner) /* This was really a NUL. */ *yyg->yy_c_buf_p = '\0'; - else - { /* need more input */ + 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; + 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); + return yyinput(yyscanner); #else - return input(yyscanner); + return input(yyscanner); #endif - } + } - case EOB_ACT_CONTINUE_SCAN: - yyg->yy_c_buf_p = yyg->yytext_ptr + offset; - break; - } + 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 */ + /* %% [19.0] update BOL and yylineno */ if ( c == '\n' ) - - do{ yylineno++; - yycolumn=0; - }while(0) -; + + do { + yylineno++; + yycolumn=0; + } while(0) + ; return c; } @@ -1838,17 +1806,17 @@ static int yy_get_next_buffer (yyscan_t yyscanner) * @note This function does not reset the start condition to @c INITIAL . */ /* %if-c-only */ - void promela_restart (FILE * input_file , yyscan_t yyscanner) +void promela_restart (FILE * input_file , yyscan_t yyscanner) /* %endif */ /* %if-c++-only */ /* %endif */ { - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - if ( ! YY_CURRENT_BUFFER ){ - promela_ensure_buffer_stack (yyscanner); + if ( ! YY_CURRENT_BUFFER ) { + promela_ensure_buffer_stack (yyscanner); YY_CURRENT_BUFFER_LVALUE = - promela__create_buffer(yyin,YY_BUF_SIZE ,yyscanner); + promela__create_buffer(yyin,YY_BUF_SIZE ,yyscanner); } promela__init_buffer(YY_CURRENT_BUFFER,input_file ,yyscanner); @@ -1860,29 +1828,28 @@ static int yy_get_next_buffer (yyscan_t yyscanner) * @param yyscanner The scanner object. */ /* %if-c-only */ - void promela__switch_to_buffer (YY_BUFFER_STATE new_buffer , yyscan_t yyscanner) +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; + 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 ) - { + 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 ); @@ -1901,7 +1868,7 @@ static void promela__load_buffer_state (yyscan_t yyscanner) /* %if-c++-only */ /* %endif */ { - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + 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; @@ -1915,13 +1882,13 @@ static void promela__load_buffer_state (yyscan_t yyscanner) * @return the allocated buffer state. */ /* %if-c-only */ - YY_BUFFER_STATE promela__create_buffer (FILE * file, int size , yyscan_t yyscanner) +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()" ); @@ -1947,12 +1914,12 @@ static void promela__load_buffer_state (yyscan_t yyscanner) * @param yyscanner The scanner object. */ /* %if-c-only */ - void promela__delete_buffer (YY_BUFFER_STATE b , yyscan_t yyscanner) +void promela__delete_buffer (YY_BUFFER_STATE b , yyscan_t yyscanner) /* %endif */ /* %if-c++-only */ /* %endif */ { - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; if ( ! b ) return; @@ -1978,36 +1945,36 @@ static void promela__load_buffer_state (yyscan_t yyscanner) * 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) +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; + 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 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 */ + /* %if-c-only */ - b->yy_is_interactive = 0; - -/* %endif */ -/* %if-c++-only */ -/* %endif */ + b->yy_is_interactive = 0; + + /* %endif */ + /* %if-c++-only */ + /* %endif */ errno = oerrno; } @@ -2016,12 +1983,12 @@ static void promela__load_buffer_state (yyscan_t yyscanner) * @param yyscanner The scanner object. */ /* %if-c-only */ - void promela__flush_buffer (YY_BUFFER_STATE b , yyscan_t yyscanner) +void promela__flush_buffer (YY_BUFFER_STATE b , yyscan_t yyscanner) /* %endif */ /* %if-c++-only */ /* %endif */ { - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; if ( ! b ) return; @@ -2056,20 +2023,19 @@ void promela_push_buffer_state (YY_BUFFER_STATE new_buffer , yyscan_t yyscanner) /* %if-c++-only */ /* %endif */ { - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + 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 ) - { + 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) @@ -2093,7 +2059,7 @@ void promela_pop_buffer_state (yyscan_t yyscanner) /* %if-c++-only */ /* %endif */ { - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; if (!YY_CURRENT_BUFFER) return; @@ -2120,38 +2086,38 @@ static void promela_ensure_buffer_stack (yyscan_t yyscanner) /* %endif */ { yy_size_t num_to_alloc; - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + 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); + (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){ + 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); + (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()" ); @@ -2167,15 +2133,14 @@ static void promela_ensure_buffer_stack (yyscan_t yyscanner) * @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. + * @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 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 ) + 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; @@ -2208,9 +2173,8 @@ YY_BUFFER_STATE promela__scan_buffer (char * base, yy_size_t size , yyscan_t y * @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) -{ - +YY_BUFFER_STATE promela__scan_string (yyconst char * yystr , yyscan_t yyscanner) { + return promela__scan_bytes(yystr,strlen(yystr) ,yyscanner); } /* %endif */ @@ -2223,12 +2187,11 @@ YY_BUFFER_STATE promela__scan_string (yyconst char * yystr , yyscan_t yyscanner) * @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 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 ); @@ -2258,9 +2221,8 @@ YY_BUFFER_STATE promela__scan_bytes (yyconst char * yybytes, yy_size_t _yybyte #endif /* %if-c-only */ -static void yy_fatal_error (yyconst char* msg , yyscan_t yyscanner) -{ - (void) fprintf( stderr, "%s\n", msg ); +static void yy_fatal_error (yyconst char* msg , yyscan_t yyscanner) { + (void) fprintf( stderr, "%s\n", msg ); exit( YY_EXIT_FAILURE ); } /* %endif */ @@ -2292,10 +2254,9 @@ static void yy_fatal_error (yyconst char* msg , yyscan_t yyscanner) /** 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; +YY_EXTRA_TYPE promela_get_extra (yyscan_t yyscanner) { + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + return yyextra; } /* %endif */ @@ -2303,64 +2264,58 @@ YY_EXTRA_TYPE promela_get_extra (yyscan_t yyscanner) /** 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; +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; +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; +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; +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; +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; +char *promela_get_text (yyscan_t yyscanner) { + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + return yytext; } /* %if-reentrant */ @@ -2369,10 +2324,9 @@ char *promela_get_text (yyscan_t yyscanner) * @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 ; +void promela_set_extra (YY_EXTRA_TYPE user_defined , yyscan_t yyscanner) { + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + yyextra = user_defined ; } /* %endif */ @@ -2381,30 +2335,28 @@ void promela_set_extra (YY_EXTRA_TYPE user_defined , yyscan_t yyscanner) * @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; +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; + /* 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; +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; + /* 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 @@ -2413,28 +2365,24 @@ void promela_set_column (int column_no , yyscan_t yyscanner) * @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_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 ; +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; +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 ; +void promela_set_debug (int bdebug , yyscan_t yyscanner) { + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + yy_flex_debug = bdebug ; } /* %endif */ @@ -2444,30 +2392,26 @@ void promela_set_debug (int bdebug , yyscan_t yyscanner) /* %if-bison-bridge */ -YYSTYPE * promela_get_lval (yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - return yylval; +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; +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; +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; + +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 */ @@ -2480,22 +2424,22 @@ void promela_set_lloc (YYLTYPE * yylloc_param , yyscan_t yyscanner) int promela_lex_init(yyscan_t* ptr_yy_globals) { - if (ptr_yy_globals == NULL){ - errno = EINVAL; - return 1; - } + if (ptr_yy_globals == NULL) { + errno = EINVAL; + return 1; + } - *ptr_yy_globals = (yyscan_t) promela_alloc ( sizeof( struct yyguts_t ), NULL ); + *ptr_yy_globals = (yyscan_t) promela_alloc ( sizeof( struct yyguts_t ), NULL ); - if (*ptr_yy_globals == NULL){ - errno = ENOMEM; - return 1; - } + 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)); + /* 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 ); + return yy_init_globals ( *ptr_yy_globals ); } /* promela_lex_init_extra has the same functionality as promela_lex_init, but follows the @@ -2509,76 +2453,74 @@ int promela_lex_init(yyscan_t* ptr_yy_globals) 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 ); + 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 */ +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; + yyin = stdin; + yyout = stdout; #else - yyin = (FILE *) 0; - yyout = (FILE *) 0; + yyin = (FILE *) 0; + yyout = (FILE *) 0; #endif - /* For future reference: Set errno on error, since we are called by - * promela_lex_init() - */ - return 0; + /* 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; +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){ + /* 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); @@ -2588,20 +2530,20 @@ int promela_lex_destroy (yyscan_t yyscanner) 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; + /* 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); + /* 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; + /* %if-reentrant */ + /* Destroy the main struct (reentrant only). */ + promela_free ( yyscanner , yyscanner ); + yyscanner = NULL; + /* %endif */ + return 0; } /* %endif */ @@ -2610,8 +2552,7 @@ int promela_lex_destroy (yyscan_t yyscanner) */ #ifndef yytext_ptr -static void yy_flex_strncpy (char* s1, yyconst char * s2, int n , yyscan_t yyscanner) -{ +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]; @@ -2619,8 +2560,7 @@ static void yy_flex_strncpy (char* s1, yyconst char * s2, int n , yyscan_t yysca #endif #ifdef YY_NEED_STRLEN -static int yy_flex_strlen (yyconst char * s , yyscan_t yyscanner) -{ +static int yy_flex_strlen (yyconst char * s , yyscan_t yyscanner) { register int n; for ( n = 0; s[n]; ++n ) ; @@ -2629,13 +2569,11 @@ static int yy_flex_strlen (yyconst char * s , yyscan_t yyscanner) } #endif -void *promela_alloc (yy_size_t size , yyscan_t yyscanner) -{ +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) -{ +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 @@ -2646,8 +2584,7 @@ void *promela_realloc (void * ptr, yy_size_t size , yyscan_t yyscanner) return (void *) realloc( (char *) ptr, size ); } -void promela_free (void * ptr , yyscan_t yyscanner) -{ +void promela_free (void * ptr , yyscan_t yyscanner) { free( (char *) ptr ); /* see promela_realloc() for (char *) cast */ } diff --git a/src/uscxml/plugins/datamodel/promela/parser/promela.tab.cpp b/src/uscxml/plugins/datamodel/promela/parser/promela.tab.cpp index 9d957e7..05ca549 100644 --- a/src/uscxml/plugins/datamodel/promela/parser/promela.tab.cpp +++ b/src/uscxml/plugins/datamodel/promela/parser/promela.tab.cpp @@ -1,19 +1,19 @@ /* 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 <http://www.gnu.org/licenses/>. */ @@ -26,7 +26,7 @@ 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. */ @@ -130,97 +130,96 @@ extern int promela_debug; /* 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 - }; +/* 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 */ +typedef union PROMELA_STYPE { + /* Line 387 of yacc.c */ #line 39 "promela.ypp" - uscxml::PromelaParserNode* node; + uscxml::PromelaParserNode* node; char* value; -/* Line 387 of yacc.c */ + /* Line 387 of yacc.c */ #line 225 "promela.tab.cpp" } PROMELA_STYPE; # define PROMELA_STYPE_IS_TRIVIAL 1 @@ -229,12 +228,11 @@ typedef union PROMELA_STYPE #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; +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 @@ -349,10 +347,10 @@ YYID (int yyi) #else static int YYID (yyi) - int yyi; +int yyi; #endif { - return yyi; + return yyi; } #endif @@ -376,7 +374,7 @@ YYID (yyi) # if ! defined _ALLOCA_H && ! defined EXIT_SUCCESS && (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) # include <stdlib.h> /* INFRINGES ON USER NAME SPACE */ - /* Use EXIT_SUCCESS as a witness for stdlib.h. */ +/* Use EXIT_SUCCESS as a witness for stdlib.h. */ # ifndef EXIT_SUCCESS # define EXIT_SUCCESS 0 # endif @@ -386,13 +384,13 @@ YYID (yyi) # endif # ifdef YYSTACK_ALLOC - /* Pacify GCC's `empty if-body' warning. */ +/* 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. */ +/* 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 @@ -433,11 +431,10 @@ void free (void *); /* INFRINGES ON USER NAME SPACE */ && 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; +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. */ @@ -511,273 +508,260 @@ union yyalloc ((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 +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 +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 +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 +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 +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 +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 +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 +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 +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 +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 +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 +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 +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) \ @@ -786,58 +770,56 @@ static const yytype_int16 yytable[] = #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 +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 +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) @@ -859,10 +841,10 @@ static const yytype_uint8 yystos[] = #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. */ +/* 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) @@ -933,31 +915,27 @@ yy_location_print_ (FILE *yyo, YYLTYPE const * const yylocp) #else static unsigned yy_location_print_ (yyo, yylocp) - FILE *yyo; - YYLTYPE const * const 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; - } + 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)) @@ -1013,28 +991,28 @@ yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvalue #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; +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); + FILE *yyo = yyoutput; + YYUSE (yyo); + if (!yyvaluep) + return; + YYUSE (yylocationp); + YYUSE (ctx); + YYUSE (scanner); # ifdef YYPRINT - if (yytype < YYNTOKENS) - YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep); + if (yytype < YYNTOKENS) + YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep); # else - YYUSE (yyoutput); + YYUSE (yyoutput); # endif - YYUSE (yytype); + YYUSE (yytype); } @@ -1049,23 +1027,23 @@ yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, YYL #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; +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, ")"); + 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, ")"); } /*------------------------------------------------------------------. @@ -1080,17 +1058,16 @@ yy_stack_print (yytype_int16 *yybottom, yytype_int16 *yytop) #else static void yy_stack_print (yybottom, yytop) - yytype_int16 *yybottom; - yytype_int16 *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"); + YYFPRINTF (stderr, "Stack now"); + for (; yybottom <= yytop; yybottom++) { + int yybot = *yybottom; + YYFPRINTF (stderr, " %d", yybot); + } + YYFPRINTF (stderr, "\n"); } # define YY_STACK_PRINT(Bottom, Top) \ @@ -1111,27 +1088,26 @@ yy_reduce_print (YYSTYPE *yyvsp, YYLTYPE *yylsp, int yyrule, uscxml::PromelaPars #else static void yy_reduce_print (yyvsp, yylsp, yyrule, ctx, scanner) - YYSTYPE *yyvsp; - YYLTYPE *yylsp; - int yyrule; - uscxml::PromelaParser* ctx; - void * 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"); - } + 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) \ @@ -1182,13 +1158,13 @@ yystrlen (const char *yystr) #else static YYSIZE_T yystrlen (yystr) - const char *yystr; +const char *yystr; #endif { - YYSIZE_T yylen; - for (yylen = 0; yystr[yylen]; yylen++) - continue; - return yylen; + YYSIZE_T yylen; + for (yylen = 0; yystr[yylen]; yylen++) + continue; + return yylen; } # endif # endif @@ -1206,17 +1182,17 @@ yystpcpy (char *yydest, const char *yysrc) #else static char * yystpcpy (yydest, yysrc) - char *yydest; - const char *yysrc; +char *yydest; +const char *yysrc; #endif { - char *yyd = yydest; - const char *yys = yysrc; + char *yyd = yydest; + const char *yys = yysrc; - while ((*yyd++ = *yys++) != '\0') - continue; + while ((*yyd++ = *yys++) != '\0') + continue; - return yyd - 1; + return yyd - 1; } # endif # endif @@ -1230,42 +1206,40 @@ yystpcpy (yydest, yysrc) 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; +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 @@ -1279,133 +1253,123 @@ yytnamerr (char *yyres, const char *yystr) 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 - <http://lists.gnu.org/archive/html/bison-patches/2009-12/msg00024.html> - 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) - { + 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 + <http://lists.gnu.org/archive/html/bison-patches/2009-12/msg00024.html> + 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")); + 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; + } + + { + 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 */ @@ -1421,24 +1385,24 @@ yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep, YYLTYPE *yylocatio #else static void yydestruct (yymsg, yytype, yyvaluep, yylocationp, ctx, scanner) - const char *yymsg; - int yytype; - YYSTYPE *yyvaluep; - YYLTYPE *yylocationp; - uscxml::PromelaParser* ctx; - void * scanner; +const char *yymsg; +int yytype; +YYSTYPE *yyvaluep; +YYLTYPE *yylocationp; +uscxml::PromelaParser* ctx; +void * scanner; #endif { - YYUSE (yyvaluep); - YYUSE (yylocationp); - YYUSE (ctx); - YYUSE (scanner); + YYUSE (yyvaluep); + YYUSE (yylocationp); + YYUSE (ctx); + YYUSE (scanner); - if (!yymsg) - yymsg = "Deleting"; - YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp); + if (!yymsg) + yymsg = "Deleting"; + YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp); - YYUSE (yytype); + YYUSE (yytype); } @@ -1456,7 +1420,7 @@ yyparse (void *YYPARSE_PARAM) #else int yyparse (YYPARSE_PARAM) - void *YYPARSE_PARAM; +void *YYPARSE_PARAM; #endif #else /* ! YYPARSE_PARAM */ #if (defined __STDC__ || defined __C99__FUNC__ \ @@ -1466,17 +1430,17 @@ yyparse (uscxml::PromelaParser* ctx, void * scanner) #else int yyparse (ctx, scanner) - uscxml::PromelaParser* ctx; - void * scanner; +uscxml::PromelaParser* ctx; +void * scanner; #endif #endif { -/* The lookahead symbol. */ -int yychar; + /* The lookahead symbol. */ + int yychar; #if defined __GNUC__ && 407 <= __GNUC__ * 100 + __GNUC_MINOR__ -/* Suppress an incorrect diagnostic about yylval being uninitialized. */ + /* Suppress an incorrect diagnostic about yylval being uninitialized. */ # define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN \ _Pragma ("GCC diagnostic push") \ _Pragma ("GCC diagnostic ignored \"-Wuninitialized\"")\ @@ -1484,16 +1448,16 @@ int yychar; # 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; + /* 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 + static YYLTYPE yyloc_default # if defined PROMELA_LTYPE_IS_TRIVIAL && PROMELA_LTYPE_IS_TRIVIAL - = { 1, 1, 1, 1 } + = { 1, 1, 1, 1 } # endif -; + ; #ifndef YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN # define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN # define YY_IGNORE_MAYBE_UNINITIALIZED_END @@ -1502,1020 +1466,1165 @@ static YYLTYPE yyloc_default # define YY_INITIAL_VALUE(Value) /* Nothing. */ #endif -/* The semantic value of the lookahead symbol. */ -YYSTYPE yylval YY_INITIAL_VALUE(yyval_default); + /* The semantic value of the lookahead symbol. */ + YYSTYPE yylval YY_INITIAL_VALUE(yyval_default); -/* Location data for the lookahead symbol. */ -YYLTYPE yylloc = yyloc_default; + /* Location data for the lookahead symbol. */ + YYLTYPE yylloc = yyloc_default; - /* Number of syntax errors so far. */ - int yynerrs; + /* Number of syntax errors so far. */ + int yynerrs; - int yystate; - /* Number of tokens to shift before error messages enabled. */ - int yyerrstatus; + 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. + /* 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. */ + 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 state stack. */ + yytype_int16 yyssa[YYINITDEPTH]; + yytype_int16 *yyss; + yytype_int16 *yyssp; - /* The semantic value stack. */ - YYSTYPE yyvsa[YYINITDEPTH]; - YYSTYPE *yyvs; - YYSTYPE *yyvsp; + /* The semantic value stack. */ + YYSTYPE yyvsa[YYINITDEPTH]; + YYSTYPE *yyvs; + YYSTYPE *yyvsp; - /* The location stack. */ - YYLTYPE yylsa[YYINITDEPTH]; - YYLTYPE *yyls; - YYLTYPE *yylsp; + /* The location stack. */ + YYLTYPE yylsa[YYINITDEPTH]; + YYLTYPE *yyls; + YYLTYPE *yylsp; - /* The locations where the error started and ended. */ - YYLTYPE yyerror_range[3]; + /* The locations where the error started and ended. */ + YYLTYPE yyerror_range[3]; - YYSIZE_T yystacksize; + 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; + 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; + /* 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; + /* 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; + yyssp = yyss = yyssa; + yyvsp = yyvs = yyvsa; + yylsp = yyls = yylsa; + yystacksize = YYINITDEPTH; - YYDPRINTF ((stderr, "Starting parse\n")); + YYDPRINTF ((stderr, "Starting parse\n")); - yystate = 0; - yyerrstatus = 0; - yynerrs = 0; - yychar = YYEMPTY; /* Cause a token to be read. */ - yylsp[0] = yylloc; - goto yysetstate; + 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++; + /*------------------------------------------------------------. + | 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; +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; + 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; - } + { + /* 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; + 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); + /* 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); - } + if (yyss1 != yyssa) + YYSTACK_FREE (yyss1); + } # endif #endif /* no yyoverflow */ - yyssp = yyss + yysize - 1; - yyvsp = yyvs + yysize - 1; - yylsp = yyls + yysize - 1; + yyssp = yyss + yysize - 1; + yyvsp = yyvs + yysize - 1; + yylsp = yyls + yysize - 1; - YYDPRINTF ((stderr, "Stack size increased to %lu\n", - (unsigned long int) yystacksize)); + YYDPRINTF ((stderr, "Stack size increased to %lu\n", + (unsigned long int) yystacksize)); - if (yyss + yystacksize - 1 <= yyssp) - YYABORT; - } + if (yyss + yystacksize - 1 <= yyssp) + YYABORT; + } - YYDPRINTF ((stderr, "Entering state %d\n", yystate)); + YYDPRINTF ((stderr, "Entering state %d\n", yystate)); - if (yystate == YYFINAL) - YYACCEPT; + if (yystate == YYFINAL) + YYACCEPT; - goto yybackup; + goto yybackup; -/*-----------. -| 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. | -`-----------------------------------------------------------*/ + /* 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; + yyn = yydefact[yystate]; + if (yyn == 0) + goto yyerrlab; + goto yyreduce; -/*-----------------------------. -| yyreduce -- Do a reduction. | -`-----------------------------*/ + /*-----------------------------. + | 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 */ + /* 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 */ + { + 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 */ + { + 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 */ + { + 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; + { + (yyval.node) = (yyvsp[(1) - (1)].node); + } + break; - case 6: -/* Line 1787 of yacc.c */ + 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; + { + (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 */ + 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; + { + (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 */ + 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); - } + { + 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)); } - break; + } else { + (yyval.node) = (yyvsp[(1) - (2)].node); + } + } + break; - case 9: -/* Line 1787 of yacc.c */ + case 9: + /* Line 1787 of yacc.c */ #line 121 "promela.ypp" - { (yyval.node) = NULL; } - break; + { + (yyval.node) = NULL; + } + break; - case 10: -/* Line 1787 of yacc.c */ + case 10: + /* Line 1787 of yacc.c */ #line 122 "promela.ypp" - { (yyval.node) = (yyvsp[(2) - (2)].node); } - break; + { + (yyval.node) = (yyvsp[(2) - (2)].node); + } + break; - case 11: -/* Line 1787 of yacc.c */ + case 11: + /* Line 1787 of yacc.c */ #line 132 "promela.ypp" - { (yyval.node) = (yyvsp[(2) - (3)].node); } - break; + { + (yyval.node) = (yyvsp[(2) - (3)].node); + } + break; - case 12: -/* Line 1787 of yacc.c */ + 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; + { + (yyval.node) = ctx->node(PML_PLUS, 2, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node)); + } + break; - case 13: -/* Line 1787 of yacc.c */ + 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; + { + (yyval.node) = ctx->node(PML_MINUS, 2, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node)); + } + break; - case 14: -/* Line 1787 of yacc.c */ + 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; + { + (yyval.node) = ctx->node(PML_TIMES, 2, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node)); + } + break; - case 15: -/* Line 1787 of yacc.c */ + 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; + { + (yyval.node) = ctx->node(PML_DIVIDE, 2, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node)); + } + break; - case 16: -/* Line 1787 of yacc.c */ + 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; + { + (yyval.node) = ctx->node(PML_MODULO, 2, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node)); + } + break; - case 17: -/* Line 1787 of yacc.c */ + 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; + { + (yyval.node) = ctx->node(PML_BITAND, 2, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node)); + } + break; - case 18: -/* Line 1787 of yacc.c */ + 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; + { + (yyval.node) = ctx->node(PML_BITXOR, 2, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node)); + } + break; - case 19: -/* Line 1787 of yacc.c */ + 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; + { + (yyval.node) = ctx->node(PML_BITOR, 2, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node)); + } + break; - case 20: -/* Line 1787 of yacc.c */ + 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; + { + (yyval.node) = ctx->node(PML_GT, 2, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node)); + } + break; - case 21: -/* Line 1787 of yacc.c */ + 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; + { + (yyval.node) = ctx->node(PML_LT, 2, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node)); + } + break; - case 22: -/* Line 1787 of yacc.c */ + 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; + { + (yyval.node) = ctx->node(PML_GE, 2, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node)); + } + break; - case 23: -/* Line 1787 of yacc.c */ + 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; + { + (yyval.node) = ctx->node(PML_LE, 2, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node)); + } + break; - case 24: -/* Line 1787 of yacc.c */ + 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; + { + (yyval.node) = ctx->node(PML_EQ, 2, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node)); + } + break; - case 25: -/* Line 1787 of yacc.c */ + 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; + { + (yyval.node) = ctx->node(PML_NE, 2, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node)); + } + break; - case 26: -/* Line 1787 of yacc.c */ + 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; + { + (yyval.node) = ctx->node(PML_AND, 2, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node)); + } + break; - case 27: -/* Line 1787 of yacc.c */ + 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; + { + (yyval.node) = ctx->node(PML_OR, 2, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node)); + } + break; - case 28: -/* Line 1787 of yacc.c */ + 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; + { + (yyval.node) = ctx->node(PML_LSHIFT, 2, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node)); + } + break; - case 29: -/* Line 1787 of yacc.c */ + 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; + { + (yyval.node) = ctx->node(PML_RSHIFT, 2, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node)); + } + break; - case 30: -/* Line 1787 of yacc.c */ + case 30: + /* Line 1787 of yacc.c */ #line 151 "promela.ypp" - { (yyval.node) = ctx->node(PML_NEG, 1, (yyvsp[(2) - (2)].node)); } - break; + { + (yyval.node) = ctx->node(PML_NEG, 1, (yyvsp[(2) - (2)].node)); + } + break; - case 31: -/* Line 1787 of yacc.c */ + case 31: + /* Line 1787 of yacc.c */ #line 152 "promela.ypp" - { (yyval.node) = ctx->node(PML_MINUS, 1, (yyvsp[(2) - (2)].node)); } - break; + { + (yyval.node) = ctx->node(PML_MINUS, 1, (yyvsp[(2) - (2)].node)); + } + break; - case 32: -/* Line 1787 of yacc.c */ + case 32: + /* Line 1787 of yacc.c */ #line 154 "promela.ypp" - { (yyval.node) = ctx->node(PML_LEN, 1, (yyvsp[(3) - (4)].node)); } - break; + { + (yyval.node) = ctx->node(PML_LEN, 1, (yyvsp[(3) - (4)].node)); + } + break; - case 33: -/* Line 1787 of yacc.c */ + case 33: + /* Line 1787 of yacc.c */ #line 155 "promela.ypp" - { (yyval.node) = (yyvsp[(1) - (1)].node); } - break; + { + (yyval.node) = (yyvsp[(1) - (1)].node); + } + break; - case 34: -/* Line 1787 of yacc.c */ + 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; + { + (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 */ + 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; + { + /* 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 */ + case 36: + /* Line 1787 of yacc.c */ #line 163 "promela.ypp" - { (yyval.node) = ctx->node(PML_SHOW, 0); } - break; + { + (yyval.node) = ctx->node(PML_SHOW, 0); + } + break; - case 37: -/* Line 1787 of yacc.c */ + case 37: + /* Line 1787 of yacc.c */ #line 164 "promela.ypp" - { (yyval.node) = ctx->node(PML_HIDDEN, 0); } - break; + { + (yyval.node) = ctx->node(PML_HIDDEN, 0); + } + break; - case 38: -/* Line 1787 of yacc.c */ + case 38: + /* Line 1787 of yacc.c */ #line 165 "promela.ypp" - { (yyval.node) = ctx->node(PML_SHOW, 0); } - break; + { + (yyval.node) = ctx->node(PML_SHOW, 0); + } + break; - case 39: -/* Line 1787 of yacc.c */ + case 39: + /* Line 1787 of yacc.c */ #line 166 "promela.ypp" - { (yyval.node) = ctx->node(PML_ISLOCAL, 0); } - break; + { + (yyval.node) = ctx->node(PML_ISLOCAL, 0); + } + break; - case 40: -/* Line 1787 of yacc.c */ + 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; + { + (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 */ + 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; + { + (yyval.node) = ctx->node(PML_UNAME, 2, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node)); + } + break; - case 42: -/* Line 1787 of yacc.c */ + 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; + { + (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 */ + case 43: + /* Line 1787 of yacc.c */ #line 172 "promela.ypp" - { (yyval.node) = (yyvsp[(2) - (2)].node); } - break; + { + (yyval.node) = (yyvsp[(2) - (2)].node); + } + break; - case 44: -/* Line 1787 of yacc.c */ + 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; + { + (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 */ + case 45: + /* Line 1787 of yacc.c */ #line 178 "promela.ypp" - { (yyval.node) = (yyvsp[(1) - (1)].node); } - break; + { + (yyval.node) = (yyvsp[(1) - (1)].node); + } + break; - case 46: -/* Line 1787 of yacc.c */ + case 46: + /* Line 1787 of yacc.c */ #line 179 "promela.ypp" - { (yyval.node) = (yyvsp[(1) - (2)].node); } - break; + { + (yyval.node) = (yyvsp[(1) - (2)].node); + } + break; - case 47: -/* Line 1787 of yacc.c */ + 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 */ + { + (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; + { + (yyval.node) = ctx->node(PML_VARLIST, 1, (yyvsp[(1) - (1)].node)); + } + break; - case 49: -/* Line 1787 of yacc.c */ + 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; + { + (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 */ + case 50: + /* Line 1787 of yacc.c */ #line 194 "promela.ypp" - { (yyval.node) = (yyvsp[(1) - (1)].node); } - break; + { + (yyval.node) = (yyvsp[(1) - (1)].node); + } + break; - case 51: -/* Line 1787 of yacc.c */ + 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; + { + (yyval.node) = ctx->node(PML_ASGN, 2, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node)); + } + break; - case 52: -/* Line 1787 of yacc.c */ + 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; + { + (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 */ + 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; + { + (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 */ + 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; + { + (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 */ + 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; + { + (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 */ + case 56: + /* Line 1787 of yacc.c */ #line 204 "promela.ypp" - { (yyval.node) = ctx->node(PML_MINUS, 1, (yyvsp[(2) - (2)].node)); } - break; + { + (yyval.node) = ctx->node(PML_MINUS, 1, (yyvsp[(2) - (2)].node)); + } + break; - case 57: -/* Line 1787 of yacc.c */ + case 57: + /* Line 1787 of yacc.c */ #line 205 "promela.ypp" - { (yyval.node) = (yyvsp[(2) - (3)].node); } - break; + { + (yyval.node) = (yyvsp[(2) - (3)].node); + } + break; - case 58: -/* Line 1787 of yacc.c */ + 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; + { + (yyval.node) = ctx->node(PML_PLUS, 2, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node)); + } + break; - case 59: -/* Line 1787 of yacc.c */ + 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; + { + (yyval.node) = ctx->node(PML_MINUS, 2, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node)); + } + break; - case 60: -/* Line 1787 of yacc.c */ + 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; + { + (yyval.node) = ctx->node(PML_TIMES, 2, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node)); + } + break; - case 61: -/* Line 1787 of yacc.c */ + 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; + { + (yyval.node) = ctx->node(PML_DIVIDE, 2, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node)); + } + break; - case 62: -/* Line 1787 of yacc.c */ + 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; + { + (yyval.node) = ctx->node(PML_MODULO, 2, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node)); + } + break; - case 63: -/* Line 1787 of yacc.c */ + 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; + { + (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 */ + 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 */ + { + 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; + { + (yyval.node) = (yyvsp[(1) - (2)].node); + } + break; - case 66: -/* Line 1787 of yacc.c */ + case 66: + /* Line 1787 of yacc.c */ #line 226 "promela.ypp" - { (yyval.node) = (yyvsp[(1) - (1)].node); } - break; + { + (yyval.node) = (yyvsp[(1) - (1)].node); + } + break; - case 67: -/* Line 1787 of yacc.c */ + case 67: + /* Line 1787 of yacc.c */ #line 227 "promela.ypp" - { (yyval.node) = (yyvsp[(1) - (2)].node); } - break; + { + (yyval.node) = (yyvsp[(1) - (2)].node); + } + break; - case 68: -/* Line 1787 of yacc.c */ + 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; + { + (yyval.node) = ctx->node(PML_STMNT, 2, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node)); + } + break; - case 69: -/* Line 1787 of yacc.c */ + case 69: + /* Line 1787 of yacc.c */ #line 231 "promela.ypp" - { (yyval.node) = (yyvsp[(1) - (1)].node); } - break; + { + (yyval.node) = (yyvsp[(1) - (1)].node); + } + break; - case 70: -/* Line 1787 of yacc.c */ + 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; + { + (yyval.node) = ctx->node(PML_ASGN, 2, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node)); + } + break; - case 71: -/* Line 1787 of yacc.c */ + case 71: + /* Line 1787 of yacc.c */ #line 235 "promela.ypp" - { (yyval.node) = ctx->node(PML_INCR, 1, (yyvsp[(1) - (2)].node)); } - break; + { + (yyval.node) = ctx->node(PML_INCR, 1, (yyvsp[(1) - (2)].node)); + } + break; - case 72: -/* Line 1787 of yacc.c */ + case 72: + /* Line 1787 of yacc.c */ #line 236 "promela.ypp" - { (yyval.node) = ctx->node(PML_DECR, 1, (yyvsp[(1) - (2)].node)); } - break; + { + (yyval.node) = ctx->node(PML_DECR, 1, (yyvsp[(1) - (2)].node)); + } + break; - case 73: -/* Line 1787 of yacc.c */ + 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; + { + (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 */ + case 74: + /* Line 1787 of yacc.c */ #line 238 "promela.ypp" - { (yyval.node) = ctx->node(PML_PRINT, 1, (yyvsp[(3) - (4)].node)); } - break; + { + (yyval.node) = ctx->node(PML_PRINT, 1, (yyvsp[(3) - (4)].node)); + } + break; - case 75: -/* Line 1787 of yacc.c */ + 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; + { + (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 */ + case 76: + /* Line 1787 of yacc.c */ #line 240 "promela.ypp" - { (yyval.node) = ctx->node(PML_ASSERT, 1, (yyvsp[(2) - (2)].node)); } - break; + { + (yyval.node) = ctx->node(PML_ASSERT, 1, (yyvsp[(2) - (2)].node)); + } + break; - case 77: -/* Line 1787 of yacc.c */ + case 77: + /* Line 1787 of yacc.c */ #line 241 "promela.ypp" - { (yyval.node) = (yyvsp[(1) - (1)].node); } - break; + { + (yyval.node) = (yyvsp[(1) - (1)].node); + } + break; - case 78: -/* Line 1787 of yacc.c */ + case 78: + /* Line 1787 of yacc.c */ #line 244 "promela.ypp" - { (yyval.node) = ctx->value(0, NULL, ""); } - break; + { + (yyval.node) = ctx->value(0, NULL, ""); + } + break; - case 79: -/* Line 1787 of yacc.c */ + case 79: + /* Line 1787 of yacc.c */ #line 245 "promela.ypp" - { (yyval.node) = (yyvsp[(2) - (2)].node); } - break; + { + (yyval.node) = (yyvsp[(2) - (2)].node); + } + break; - case 80: -/* Line 1787 of yacc.c */ + case 80: + /* Line 1787 of yacc.c */ #line 248 "promela.ypp" - { (yyval.node) = (yyvsp[(1) - (1)].node); } - break; + { + (yyval.node) = (yyvsp[(1) - (1)].node); + } + break; - case 81: -/* Line 1787 of yacc.c */ + 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; + { + (yyval.node) = ctx->node(0, 2, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node)); + } + break; -/* Line 1787 of yacc.c */ + /* 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 | -`------------------------------------*/ + 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; + /* 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")); + 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; - } + { + 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; + + 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; + /* Else will try to reuse lookahead token after shifting the error + token. */ + goto yyerrlab1; -/*---------------------------------------------------. -| yyerrorlab -- error raised explicitly by YYERROR. | -`---------------------------------------------------*/ + /*---------------------------------------------------. + | 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. | -`-------------------------------------------------------------*/ + /* 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; - } + 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); } - /* 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 + 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; + 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); + /* Shift the error token. */ + YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp); - yystate = yyn; - goto yynewstate; + yystate = yyn; + goto yynewstate; -/*-------------------------------------. -| yyacceptlab -- YYACCEPT comes here. | -`-------------------------------------*/ + /*-------------------------------------. + | yyacceptlab -- YYACCEPT comes here. | + `-------------------------------------*/ yyacceptlab: - yyresult = 0; - goto yyreturn; + yyresult = 0; + goto yyreturn; -/*-----------------------------------. -| yyabortlab -- YYABORT comes here. | -`-----------------------------------*/ + /*-----------------------------------. + | yyabortlab -- YYABORT comes here. | + `-----------------------------------*/ yyabortlab: - yyresult = 1; - goto yyreturn; + yyresult = 1; + goto yyreturn; #if !defined yyoverflow || YYERROR_VERBOSE -/*-------------------------------------------------. -| yyexhaustedlab -- memory exhaustion comes here. | -`-------------------------------------------------*/ + /*-------------------------------------------------. + | yyexhaustedlab -- memory exhaustion comes here. | + `-------------------------------------------------*/ yyexhaustedlab: - yyerror (&yylloc, ctx, scanner, YY_("memory exhausted")); - yyresult = 2; - /* Fall through. */ + 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); - } + 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); + if (yyss != yyssa) + YYSTACK_FREE (yyss); #endif #if YYERROR_VERBOSE - if (yymsg != yymsgbuf) - YYSTACK_FREE (yymsg); + if (yymsg != yymsgbuf) + YYSTACK_FREE (yymsg); #endif - /* Make sure YYID is used. */ - return YYID (yyresult); + /* Make sure YYID is used. */ + return YYID (yyresult); } diff --git a/src/uscxml/plugins/invoker/scxml/USCXMLInvoker.cpp b/src/uscxml/plugins/invoker/scxml/USCXMLInvoker.cpp index d3aa35f..53508e6 100644 --- a/src/uscxml/plugins/invoker/scxml/USCXMLInvoker.cpp +++ b/src/uscxml/plugins/invoker/scxml/USCXMLInvoker.cpp @@ -65,7 +65,7 @@ Data USCXMLInvoker::getDataModelVariables() { void USCXMLInvoker::send(const SendRequest& req) { if (_invokedInterpreter) - _invokedInterpreter.receive(req); + _invokedInterpreter.receive(req); } void USCXMLInvoker::cancel(const std::string sendId) { @@ -93,19 +93,19 @@ void USCXMLInvoker::invoke(const InvokeRequest& req) { if (req.elem && HAS_ATTR(req.elem, "initial")) { _invokedInterpreter.setInitalConfiguration(InterpreterImpl::tokenize(ATTR(req.elem, "initial"))); } - + DataModel dataModel(_invokedInterpreter.getImpl()->getDataModel()); _invokedInterpreter.getImpl()->setParentQueue(&_parentQueue); - // copy monitors - std::set<InterpreterMonitor*>::const_iterator monIter = _interpreter->_monitors.begin(); - while(monIter != _interpreter->_monitors.end()) { - if ((*monIter)->copyToInvokers()) { - _invokedInterpreter.getImpl()->_monitors.insert(*monIter); - } - monIter++; - } - + // copy monitors + std::set<InterpreterMonitor*>::const_iterator monIter = _interpreter->_monitors.begin(); + while(monIter != _interpreter->_monitors.end()) { + if ((*monIter)->copyToInvokers()) { + _invokedInterpreter.getImpl()->_monitors.insert(*monIter); + } + monIter++; + } + // transfer namespace prefixes _invokedInterpreter.setNameSpaceInfo(_parentInterpreter->getNameSpaceInfo()); _invokedInterpreter.getImpl()->_sessionId = req.invokeid; diff --git a/src/uscxml/plugins/invoker/xhtml/template/xhtml-invoker.inc.h b/src/uscxml/plugins/invoker/xhtml/template/xhtml-invoker.inc.h index c5a5798..971260b 100644 --- a/src/uscxml/plugins/invoker/xhtml/template/xhtml-invoker.inc.h +++ b/src/uscxml/plugins/invoker/xhtml/template/xhtml-invoker.inc.h @@ -1,691 +1,691 @@ unsigned char template_xhtml_invoker_html[] = { - 0x3c, 0x68, 0x74, 0x6d, 0x6c, 0x20, 0x78, 0x6d, 0x6c, 0x6e, 0x73, 0x3d, - 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, - 0x77, 0x33, 0x2e, 0x6f, 0x72, 0x67, 0x2f, 0x31, 0x39, 0x39, 0x39, 0x2f, - 0x78, 0x68, 0x74, 0x6d, 0x6c, 0x22, 0x3e, 0x0a, 0x09, 0x3c, 0x68, 0x65, - 0x61, 0x64, 0x3e, 0x0a, 0x09, 0x09, 0x3c, 0x6d, 0x65, 0x74, 0x61, 0x20, - 0x68, 0x74, 0x74, 0x70, 0x2d, 0x65, 0x71, 0x75, 0x69, 0x76, 0x3d, 0x22, - 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x54, 0x79, 0x70, 0x65, - 0x22, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x3d, 0x22, 0x74, - 0x65, 0x78, 0x74, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x3b, 0x63, 0x68, 0x61, - 0x72, 0x73, 0x65, 0x74, 0x3d, 0x75, 0x74, 0x66, 0x2d, 0x38, 0x22, 0x20, - 0x2f, 0x3e, 0x0a, 0x0a, 0x09, 0x09, 0x3c, 0x21, 0x2d, 0x2d, 0x20, 0x47, - 0x65, 0x74, 0x20, 0x64, 0x6f, 0x6d, 0x4c, 0x6f, 0x61, 0x64, 0x65, 0x64, - 0x20, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x20, 0x61, 0x63, 0x72, 0x6f, 0x73, - 0x73, 0x20, 0x62, 0x72, 0x6f, 0x77, 0x73, 0x65, 0x72, 0x73, 0x20, 0x2d, - 0x2d, 0x3e, 0x0a, 0x09, 0x09, 0x3c, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, - 0x20, 0x74, 0x79, 0x70, 0x65, 0x3d, 0x22, 0x74, 0x65, 0x78, 0x74, 0x2f, - 0x6a, 0x61, 0x76, 0x61, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x22, 0x3e, - 0x0a, 0x09, 0x09, 0x09, 0x2f, 0x2f, 0x20, 0x73, 0x65, 0x65, 0x20, 0x68, - 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x6f, - 0x76, 0x65, 0x72, 0x66, 0x6c, 0x6f, 0x77, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x31, 0x32, - 0x30, 0x36, 0x39, 0x33, 0x37, 0x2f, 0x6a, 0x61, 0x76, 0x61, 0x73, 0x63, - 0x72, 0x69, 0x70, 0x74, 0x2d, 0x64, 0x6f, 0x6d, 0x72, 0x65, 0x61, 0x64, - 0x79, 0x0a, 0x09, 0x09, 0x09, 0x76, 0x61, 0x72, 0x20, 0x64, 0x6f, 0x6d, - 0x4c, 0x6f, 0x61, 0x64, 0x65, 0x64, 0x20, 0x3d, 0x20, 0x66, 0x75, 0x6e, - 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x63, 0x61, 0x6c, 0x6c, 0x62, 0x61, - 0x63, 0x6b, 0x29, 0x20, 0x7b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x2f, 0x2a, - 0x20, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x20, 0x45, 0x78, - 0x70, 0x6c, 0x6f, 0x72, 0x65, 0x72, 0x20, 0x2a, 0x2f, 0x0a, 0x09, 0x09, - 0x09, 0x09, 0x2f, 0x2a, 0x40, 0x63, 0x63, 0x5f, 0x6f, 0x6e, 0x0a, 0x09, - 0x09, 0x09, 0x09, 0x40, 0x69, 0x66, 0x20, 0x28, 0x40, 0x5f, 0x77, 0x69, - 0x6e, 0x33, 0x32, 0x20, 0x7c, 0x7c, 0x20, 0x40, 0x5f, 0x77, 0x69, 0x6e, - 0x36, 0x34, 0x29, 0x09, 0x09, 0x09, 0x09, 0x09, 0x0a, 0x09, 0x09, 0x09, - 0x09, 0x09, 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x77, - 0x72, 0x69, 0x74, 0x65, 0x28, 0x27, 0x3c, 0x73, 0x63, 0x72, 0x69, 0x70, - 0x74, 0x20, 0x69, 0x64, 0x3d, 0x22, 0x69, 0x65, 0x53, 0x63, 0x72, 0x69, - 0x70, 0x74, 0x4c, 0x6f, 0x61, 0x64, 0x22, 0x20, 0x64, 0x65, 0x66, 0x65, - 0x72, 0x20, 0x73, 0x72, 0x63, 0x3d, 0x22, 0x2f, 0x2f, 0x3a, 0x22, 0x3e, - 0x3c, 0x5c, 0x2f, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x3e, 0x27, 0x29, - 0x3b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x64, 0x6f, 0x63, 0x75, 0x6d, - 0x65, 0x6e, 0x74, 0x2e, 0x67, 0x65, 0x74, 0x45, 0x6c, 0x65, 0x6d, 0x65, - 0x6e, 0x74, 0x42, 0x79, 0x49, 0x64, 0x28, 0x27, 0x69, 0x65, 0x53, 0x63, - 0x72, 0x69, 0x70, 0x74, 0x4c, 0x6f, 0x61, 0x64, 0x27, 0x29, 0x2e, 0x6f, - 0x6e, 0x72, 0x65, 0x61, 0x64, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, 0x63, - 0x68, 0x61, 0x6e, 0x67, 0x65, 0x20, 0x3d, 0x20, 0x66, 0x75, 0x6e, 0x63, - 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x29, 0x20, 0x7b, 0x0a, 0x09, 0x09, 0x09, - 0x09, 0x09, 0x09, 0x69, 0x66, 0x20, 0x28, 0x74, 0x68, 0x69, 0x73, 0x2e, - 0x72, 0x65, 0x61, 0x64, 0x79, 0x53, 0x74, 0x61, 0x74, 0x65, 0x20, 0x3d, - 0x3d, 0x20, 0x27, 0x63, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x27, - 0x29, 0x20, 0x7b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x76, - 0x61, 0x72, 0x20, 0x68, 0x65, 0x61, 0x64, 0x3d, 0x20, 0x64, 0x6f, 0x63, - 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x67, 0x65, 0x74, 0x45, 0x6c, 0x65, - 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x42, 0x79, 0x54, 0x61, 0x67, 0x4e, 0x61, - 0x6d, 0x65, 0x28, 0x27, 0x68, 0x65, 0x61, 0x64, 0x27, 0x29, 0x5b, 0x30, - 0x5d, 0x3b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x76, 0x61, - 0x72, 0x20, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x3d, 0x20, 0x64, 0x6f, - 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x63, 0x72, 0x65, 0x61, 0x74, - 0x65, 0x45, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x28, 0x27, 0x73, 0x63, - 0x72, 0x69, 0x70, 0x74, 0x27, 0x29, 0x3b, 0x0a, 0x09, 0x09, 0x09, 0x09, - 0x09, 0x09, 0x09, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x2e, 0x74, 0x79, - 0x70, 0x65, 0x3d, 0x20, 0x27, 0x74, 0x65, 0x78, 0x74, 0x2f, 0x6a, 0x61, - 0x76, 0x61, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x27, 0x3b, 0x0a, 0x09, - 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, - 0x2e, 0x73, 0x72, 0x63, 0x3d, 0x20, 0x27, 0x68, 0x74, 0x74, 0x70, 0x3a, - 0x2f, 0x2f, 0x77, 0x69, 0x63, 0x6b, 0x65, 0x64, 0x2d, 0x67, 0x6f, 0x6f, - 0x64, 0x2d, 0x78, 0x70, 0x61, 0x74, 0x68, 0x2e, 0x67, 0x6f, 0x6f, 0x67, - 0x6c, 0x65, 0x63, 0x6f, 0x64, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x66, - 0x69, 0x6c, 0x65, 0x73, 0x2f, 0x77, 0x67, 0x78, 0x70, 0x61, 0x74, 0x68, - 0x2e, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x2e, 0x6a, 0x73, 0x27, - 0x3b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x68, 0x65, 0x61, - 0x64, 0x2e, 0x61, 0x70, 0x70, 0x65, 0x6e, 0x64, 0x43, 0x68, 0x69, 0x6c, - 0x64, 0x28, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x29, 0x3b, 0x0a, 0x09, - 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x77, 0x67, 0x78, 0x70, 0x61, 0x74, - 0x68, 0x2e, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x28, 0x29, 0x3b, - 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x0a, 0x09, 0x09, 0x09, - 0x09, 0x09, 0x09, 0x09, 0x2f, 0x2f, 0x20, 0x73, 0x65, 0x65, 0x20, 0x68, - 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x6f, - 0x76, 0x65, 0x72, 0x66, 0x6c, 0x6f, 0x77, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x31, 0x38, - 0x31, 0x31, 0x31, 0x31, 0x36, 0x2f, 0x69, 0x65, 0x2d, 0x73, 0x75, 0x70, - 0x70, 0x6f, 0x72, 0x74, 0x2d, 0x66, 0x6f, 0x72, 0x2d, 0x64, 0x6f, 0x6d, - 0x2d, 0x69, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x6e, 0x6f, 0x64, 0x65, 0x0a, - 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x64, 0x6f, 0x63, 0x75, 0x6d, - 0x65, 0x6e, 0x74, 0x2e, 0x69, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x4e, 0x6f, - 0x64, 0x65, 0x20, 0x3d, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, - 0x6e, 0x28, 0x6e, 0x6f, 0x64, 0x65, 0x2c, 0x20, 0x61, 0x6c, 0x6c, 0x43, - 0x68, 0x69, 0x6c, 0x64, 0x72, 0x65, 0x6e, 0x29, 0x20, 0x7b, 0x0a, 0x09, - 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x20, 0x20, 0x73, 0x77, 0x69, 0x74, - 0x63, 0x68, 0x20, 0x28, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x6e, 0x6f, 0x64, - 0x65, 0x54, 0x79, 0x70, 0x65, 0x29, 0x20, 0x7b, 0x0a, 0x09, 0x09, 0x09, - 0x09, 0x09, 0x09, 0x09, 0x20, 0x20, 0x20, 0x20, 0x63, 0x61, 0x73, 0x65, - 0x20, 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x45, 0x4c, - 0x45, 0x4d, 0x45, 0x4e, 0x54, 0x5f, 0x4e, 0x4f, 0x44, 0x45, 0x3a, 0x0a, - 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x76, 0x61, 0x72, 0x20, 0x6e, 0x65, 0x77, 0x4e, 0x6f, 0x64, 0x65, - 0x20, 0x3d, 0x20, 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x2e, - 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x45, 0x6c, 0x65, 0x6d, 0x65, 0x6e, - 0x74, 0x4e, 0x53, 0x28, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x6e, 0x61, 0x6d, - 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x55, 0x52, 0x49, 0x2c, 0x20, 0x6e, - 0x6f, 0x64, 0x65, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x4e, 0x61, 0x6d, 0x65, - 0x29, 0x3b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x69, 0x66, 0x28, 0x6e, 0x6f, 0x64, 0x65, 0x2e, - 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x20, 0x26, - 0x26, 0x20, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x69, - 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, - 0x20, 0x3e, 0x20, 0x30, 0x29, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, - 0x09, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x66, 0x6f, 0x72, - 0x28, 0x76, 0x61, 0x72, 0x20, 0x69, 0x20, 0x3d, 0x20, 0x30, 0x2c, 0x20, - 0x69, 0x6c, 0x20, 0x3d, 0x20, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x61, 0x74, - 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x6c, 0x65, 0x6e, - 0x67, 0x74, 0x68, 0x3b, 0x20, 0x69, 0x20, 0x3c, 0x20, 0x69, 0x6c, 0x3b, - 0x20, 0x69, 0x2b, 0x2b, 0x29, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, - 0x09, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6e, - 0x65, 0x77, 0x4e, 0x6f, 0x64, 0x65, 0x2e, 0x73, 0x65, 0x74, 0x41, 0x74, - 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x28, 0x6e, 0x6f, 0x64, 0x65, - 0x2e, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x5b, - 0x69, 0x5d, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x2c, - 0x20, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x67, 0x65, 0x74, 0x41, 0x74, 0x74, - 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x28, 0x6e, 0x6f, 0x64, 0x65, 0x2e, - 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x5b, 0x69, - 0x5d, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x29, 0x29, - 0x3b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x69, 0x66, 0x28, 0x61, 0x6c, 0x6c, 0x43, 0x68, 0x69, - 0x6c, 0x64, 0x72, 0x65, 0x6e, 0x20, 0x26, 0x26, 0x20, 0x6e, 0x6f, 0x64, - 0x65, 0x2e, 0x63, 0x68, 0x69, 0x6c, 0x64, 0x4e, 0x6f, 0x64, 0x65, 0x73, - 0x20, 0x26, 0x26, 0x20, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x63, 0x68, 0x69, - 0x6c, 0x64, 0x4e, 0x6f, 0x64, 0x65, 0x73, 0x2e, 0x6c, 0x65, 0x6e, 0x67, - 0x74, 0x68, 0x20, 0x3e, 0x20, 0x30, 0x29, 0x0a, 0x09, 0x09, 0x09, 0x09, - 0x09, 0x09, 0x09, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x66, - 0x6f, 0x72, 0x28, 0x76, 0x61, 0x72, 0x20, 0x69, 0x20, 0x3d, 0x20, 0x30, - 0x2c, 0x20, 0x69, 0x6c, 0x20, 0x3d, 0x20, 0x6e, 0x6f, 0x64, 0x65, 0x2e, - 0x63, 0x68, 0x69, 0x6c, 0x64, 0x4e, 0x6f, 0x64, 0x65, 0x73, 0x2e, 0x6c, - 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3b, 0x20, 0x69, 0x20, 0x3c, 0x20, 0x69, - 0x6c, 0x3b, 0x20, 0x69, 0x2b, 0x2b, 0x29, 0x0a, 0x09, 0x09, 0x09, 0x09, - 0x09, 0x09, 0x09, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x6e, 0x65, 0x77, 0x4e, 0x6f, 0x64, 0x65, 0x2e, 0x61, 0x70, 0x70, - 0x65, 0x6e, 0x64, 0x43, 0x68, 0x69, 0x6c, 0x64, 0x28, 0x64, 0x6f, 0x63, - 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x69, 0x6d, 0x70, 0x6f, 0x72, 0x74, - 0x4e, 0x6f, 0x64, 0x65, 0x28, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x63, 0x68, - 0x69, 0x6c, 0x64, 0x4e, 0x6f, 0x64, 0x65, 0x73, 0x5b, 0x69, 0x5d, 0x2c, - 0x20, 0x61, 0x6c, 0x6c, 0x43, 0x68, 0x69, 0x6c, 0x64, 0x72, 0x65, 0x6e, - 0x29, 0x29, 0x3b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, - 0x6e, 0x65, 0x77, 0x4e, 0x6f, 0x64, 0x65, 0x3b, 0x0a, 0x09, 0x09, 0x09, - 0x09, 0x09, 0x09, 0x09, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x62, 0x72, - 0x65, 0x61, 0x6b, 0x3b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, - 0x20, 0x20, 0x20, 0x20, 0x63, 0x61, 0x73, 0x65, 0x20, 0x64, 0x6f, 0x63, - 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x54, 0x45, 0x58, 0x54, 0x5f, 0x4e, - 0x4f, 0x44, 0x45, 0x3a, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, - 0x20, 0x20, 0x20, 0x20, 0x63, 0x61, 0x73, 0x65, 0x20, 0x64, 0x6f, 0x63, - 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x43, 0x44, 0x41, 0x54, 0x41, 0x5f, - 0x53, 0x45, 0x43, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x4e, 0x4f, 0x44, 0x45, - 0x3a, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x20, 0x20, 0x20, - 0x20, 0x63, 0x61, 0x73, 0x65, 0x20, 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, - 0x6e, 0x74, 0x2e, 0x43, 0x4f, 0x4d, 0x4d, 0x45, 0x4e, 0x54, 0x5f, 0x4e, - 0x4f, 0x44, 0x45, 0x3a, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, - 0x20, 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x63, 0x72, - 0x65, 0x61, 0x74, 0x65, 0x54, 0x65, 0x78, 0x74, 0x4e, 0x6f, 0x64, 0x65, - 0x28, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x56, 0x61, - 0x6c, 0x75, 0x65, 0x29, 0x3b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, - 0x09, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x62, 0x72, 0x65, 0x61, 0x6b, - 0x3b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x20, 0x20, 0x7d, - 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x7d, 0x0a, 0x09, 0x09, - 0x09, 0x09, 0x09, 0x09, 0x09, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, - 0x09, 0x63, 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x28, 0x29, 0x3b, - 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x7d, 0x0a, 0x09, 0x09, 0x09, - 0x09, 0x09, 0x7d, 0x3b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x40, 0x65, 0x6e, - 0x64, 0x20, 0x40, 0x2a, 0x2f, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x2f, 0x2a, - 0x20, 0x4d, 0x6f, 0x7a, 0x69, 0x6c, 0x6c, 0x61, 0x2c, 0x20, 0x43, 0x68, - 0x72, 0x6f, 0x6d, 0x65, 0x2c, 0x20, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x20, - 0x2a, 0x2f, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x69, 0x66, 0x20, 0x28, 0x64, - 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x61, 0x64, 0x64, 0x45, - 0x76, 0x65, 0x6e, 0x74, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, - 0x29, 0x20, 0x7b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x64, 0x6f, 0x63, - 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x61, 0x64, 0x64, 0x45, 0x76, 0x65, - 0x6e, 0x74, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x28, 0x27, - 0x44, 0x4f, 0x4d, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x4c, 0x6f, - 0x61, 0x64, 0x65, 0x64, 0x27, 0x2c, 0x20, 0x63, 0x61, 0x6c, 0x6c, 0x62, - 0x61, 0x63, 0x6b, 0x2c, 0x20, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x29, 0x3b, - 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, - 0x3b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x7d, 0x0a, 0x09, 0x09, 0x09, 0x09, - 0x2f, 0x2a, 0x20, 0x53, 0x61, 0x66, 0x61, 0x72, 0x69, 0x2c, 0x20, 0x69, - 0x43, 0x61, 0x62, 0x2c, 0x20, 0x4b, 0x6f, 0x6e, 0x71, 0x75, 0x65, 0x72, - 0x6f, 0x72, 0x20, 0x2a, 0x2f, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x69, 0x66, - 0x20, 0x28, 0x2f, 0x4b, 0x48, 0x54, 0x4d, 0x4c, 0x7c, 0x57, 0x65, 0x62, - 0x4b, 0x69, 0x74, 0x7c, 0x69, 0x43, 0x61, 0x62, 0x2f, 0x69, 0x2e, 0x74, - 0x65, 0x73, 0x74, 0x28, 0x6e, 0x61, 0x76, 0x69, 0x67, 0x61, 0x74, 0x6f, - 0x72, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x29, - 0x29, 0x20, 0x7b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x76, 0x61, 0x72, - 0x20, 0x44, 0x4f, 0x4d, 0x4c, 0x6f, 0x61, 0x64, 0x54, 0x69, 0x6d, 0x65, - 0x72, 0x20, 0x3d, 0x20, 0x73, 0x65, 0x74, 0x49, 0x6e, 0x74, 0x65, 0x72, - 0x76, 0x61, 0x6c, 0x28, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, - 0x20, 0x28, 0x29, 0x20, 0x7b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, - 0x69, 0x66, 0x20, 0x28, 0x2f, 0x6c, 0x6f, 0x61, 0x64, 0x65, 0x64, 0x7c, - 0x63, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x2f, 0x69, 0x2e, 0x74, - 0x65, 0x73, 0x74, 0x28, 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, - 0x2e, 0x72, 0x65, 0x61, 0x64, 0x79, 0x53, 0x74, 0x61, 0x74, 0x65, 0x29, - 0x29, 0x20, 0x7b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x63, - 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x28, 0x29, 0x3b, 0x0a, 0x09, - 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x63, 0x6c, 0x65, 0x61, 0x72, 0x49, - 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x28, 0x44, 0x4f, 0x4d, 0x4c, - 0x6f, 0x61, 0x64, 0x54, 0x69, 0x6d, 0x65, 0x72, 0x29, 0x3b, 0x0a, 0x09, - 0x09, 0x09, 0x09, 0x09, 0x09, 0x7d, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, - 0x7d, 0x2c, 0x20, 0x31, 0x30, 0x29, 0x3b, 0x0a, 0x09, 0x09, 0x09, 0x09, - 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x3b, 0x0a, 0x09, 0x09, 0x09, - 0x09, 0x7d, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x2f, 0x2a, 0x20, 0x4f, 0x74, - 0x68, 0x65, 0x72, 0x20, 0x77, 0x65, 0x62, 0x20, 0x62, 0x72, 0x6f, 0x77, - 0x73, 0x65, 0x72, 0x73, 0x20, 0x2a, 0x2f, 0x0a, 0x09, 0x09, 0x09, 0x09, - 0x77, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x2e, 0x6f, 0x6e, 0x6c, 0x6f, 0x61, - 0x64, 0x20, 0x3d, 0x20, 0x63, 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, - 0x3b, 0x0a, 0x09, 0x09, 0x09, 0x7d, 0x3b, 0x0a, 0x09, 0x09, 0x09, 0x3c, - 0x2f, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x3e, 0x0a, 0x0a, 0x09, 0x09, - 0x3c, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x20, 0x74, 0x79, 0x70, 0x65, - 0x3d, 0x22, 0x74, 0x65, 0x78, 0x74, 0x2f, 0x6a, 0x61, 0x76, 0x61, 0x73, - 0x63, 0x72, 0x69, 0x70, 0x74, 0x22, 0x3e, 0x0a, 0x09, 0x09, 0x09, 0x0a, - 0x09, 0x09, 0x09, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, - 0x43, 0x6f, 0x6d, 0x65, 0x74, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, - 0x28, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x29, 0x20, 0x7b, 0x0a, - 0x09, 0x09, 0x09, 0x09, 0x2f, 0x2a, 0x2a, 0x0a, 0x09, 0x09, 0x09, 0x09, - 0x20, 0x2a, 0x20, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x20, 0x66, - 0x6f, 0x72, 0x20, 0x74, 0x77, 0x6f, 0x2d, 0x63, 0x68, 0x61, 0x6e, 0x6e, - 0x65, 0x6c, 0x20, 0x61, 0x73, 0x79, 0x6e, 0x63, 0x68, 0x72, 0x6f, 0x6e, - 0x6f, 0x75, 0x73, 0x20, 0x68, 0x74, 0x74, 0x70, 0x20, 0x63, 0x6f, 0x6d, - 0x6d, 0x75, 0x6e, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x0a, 0x09, - 0x09, 0x09, 0x09, 0x20, 0x2a, 0x2f, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x66, - 0x6f, 0x72, 0x20, 0x28, 0x76, 0x61, 0x72, 0x20, 0x6b, 0x65, 0x79, 0x20, - 0x69, 0x6e, 0x20, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x29, 0x20, - 0x7b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x20, 0x20, 0x69, 0x66, 0x20, 0x28, - 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x68, 0x61, 0x73, 0x4f, - 0x77, 0x6e, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x28, 0x6b, - 0x65, 0x79, 0x29, 0x29, 0x20, 0x7b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x20, - 0x20, 0x20, 0x20, 0x74, 0x68, 0x69, 0x73, 0x5b, 0x6b, 0x65, 0x79, 0x5d, - 0x20, 0x3d, 0x20, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x5b, 0x6b, - 0x65, 0x79, 0x5d, 0x3b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x20, 0x20, 0x7d, - 0x0a, 0x09, 0x09, 0x09, 0x09, 0x7d, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x76, - 0x61, 0x72, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x20, 0x3d, 0x20, 0x74, 0x68, - 0x69, 0x73, 0x3b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x0a, 0x09, 0x09, 0x09, - 0x09, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x78, 0x68, 0x72, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x3d, 0x20, 0x28, 0x77, 0x69, 0x6e, 0x64, 0x6f, - 0x77, 0x2e, 0x58, 0x4d, 0x4c, 0x48, 0x74, 0x74, 0x70, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x20, 0x3f, 0x20, 0x6e, 0x65, 0x77, 0x20, 0x58, - 0x4d, 0x4c, 0x48, 0x74, 0x74, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x28, 0x29, 0x20, 0x3a, 0x20, 0x6e, 0x65, 0x77, 0x20, 0x41, 0x63, - 0x74, 0x69, 0x76, 0x65, 0x58, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x28, - 0x22, 0x4d, 0x53, 0x58, 0x4d, 0x4c, 0x32, 0x2e, 0x58, 0x4d, 0x4c, 0x48, - 0x54, 0x54, 0x50, 0x2e, 0x33, 0x2e, 0x30, 0x22, 0x29, 0x29, 0x3b, 0x0a, - 0x09, 0x09, 0x09, 0x09, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x63, 0x6f, 0x6d, - 0x65, 0x74, 0x50, 0x6f, 0x6c, 0x6c, 0x20, 0x3d, 0x20, 0x28, 0x77, 0x69, - 0x6e, 0x64, 0x6f, 0x77, 0x2e, 0x58, 0x4d, 0x4c, 0x48, 0x74, 0x74, 0x70, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x20, 0x3f, 0x20, 0x6e, 0x65, - 0x77, 0x20, 0x58, 0x4d, 0x4c, 0x48, 0x74, 0x74, 0x70, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x28, 0x29, 0x20, 0x3a, 0x20, 0x6e, 0x65, 0x77, - 0x20, 0x41, 0x63, 0x74, 0x69, 0x76, 0x65, 0x58, 0x4f, 0x62, 0x6a, 0x65, - 0x63, 0x74, 0x28, 0x22, 0x4d, 0x53, 0x58, 0x4d, 0x4c, 0x32, 0x2e, 0x58, - 0x4d, 0x4c, 0x48, 0x54, 0x54, 0x50, 0x2e, 0x33, 0x2e, 0x30, 0x22, 0x29, - 0x29, 0x3b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x0a, 0x09, 0x09, 0x09, 0x09, - 0x74, 0x68, 0x69, 0x73, 0x2e, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x55, - 0x55, 0x49, 0x44, 0x20, 0x3d, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, - 0x6f, 0x6e, 0x28, 0x29, 0x20, 0x7b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, - 0x2f, 0x2f, 0x20, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, - 0x77, 0x2e, 0x69, 0x65, 0x74, 0x66, 0x2e, 0x6f, 0x72, 0x67, 0x2f, 0x72, - 0x66, 0x63, 0x2f, 0x72, 0x66, 0x63, 0x34, 0x31, 0x32, 0x32, 0x2e, 0x74, - 0x78, 0x74, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x76, 0x61, 0x72, 0x20, - 0x73, 0x20, 0x3d, 0x20, 0x5b, 0x5d, 0x3b, 0x0a, 0x09, 0x09, 0x09, 0x09, - 0x09, 0x76, 0x61, 0x72, 0x20, 0x68, 0x65, 0x78, 0x44, 0x69, 0x67, 0x69, - 0x74, 0x73, 0x20, 0x3d, 0x20, 0x22, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, - 0x36, 0x37, 0x38, 0x39, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x22, 0x3b, - 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x66, 0x6f, 0x72, 0x20, 0x28, 0x76, - 0x61, 0x72, 0x20, 0x69, 0x20, 0x3d, 0x20, 0x30, 0x3b, 0x20, 0x69, 0x20, - 0x3c, 0x20, 0x33, 0x36, 0x3b, 0x20, 0x69, 0x2b, 0x2b, 0x29, 0x20, 0x7b, - 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x73, 0x5b, 0x69, 0x5d, 0x20, - 0x3d, 0x20, 0x68, 0x65, 0x78, 0x44, 0x69, 0x67, 0x69, 0x74, 0x73, 0x2e, - 0x73, 0x75, 0x62, 0x73, 0x74, 0x72, 0x28, 0x4d, 0x61, 0x74, 0x68, 0x2e, - 0x66, 0x6c, 0x6f, 0x6f, 0x72, 0x28, 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x72, - 0x61, 0x6e, 0x64, 0x6f, 0x6d, 0x28, 0x29, 0x20, 0x2a, 0x20, 0x30, 0x78, - 0x31, 0x30, 0x29, 0x2c, 0x20, 0x31, 0x29, 0x3b, 0x0a, 0x09, 0x09, 0x09, - 0x09, 0x09, 0x7d, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x73, 0x5b, 0x31, - 0x34, 0x5d, 0x20, 0x3d, 0x20, 0x22, 0x34, 0x22, 0x3b, 0x20, 0x20, 0x2f, - 0x2f, 0x20, 0x62, 0x69, 0x74, 0x73, 0x20, 0x31, 0x32, 0x2d, 0x31, 0x35, - 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x74, 0x69, 0x6d, 0x65, - 0x5f, 0x68, 0x69, 0x5f, 0x61, 0x6e, 0x64, 0x5f, 0x76, 0x65, 0x72, 0x73, - 0x69, 0x6f, 0x6e, 0x20, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x20, 0x74, 0x6f, - 0x20, 0x30, 0x30, 0x31, 0x30, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x73, - 0x5b, 0x31, 0x39, 0x5d, 0x20, 0x3d, 0x20, 0x68, 0x65, 0x78, 0x44, 0x69, - 0x67, 0x69, 0x74, 0x73, 0x2e, 0x73, 0x75, 0x62, 0x73, 0x74, 0x72, 0x28, - 0x28, 0x73, 0x5b, 0x31, 0x39, 0x5d, 0x20, 0x26, 0x20, 0x30, 0x78, 0x33, - 0x29, 0x20, 0x7c, 0x20, 0x30, 0x78, 0x38, 0x2c, 0x20, 0x31, 0x29, 0x3b, - 0x20, 0x20, 0x2f, 0x2f, 0x20, 0x62, 0x69, 0x74, 0x73, 0x20, 0x36, 0x2d, - 0x37, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x6c, 0x6f, - 0x63, 0x6b, 0x5f, 0x73, 0x65, 0x71, 0x5f, 0x68, 0x69, 0x5f, 0x61, 0x6e, - 0x64, 0x5f, 0x72, 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, 0x64, 0x20, 0x74, - 0x6f, 0x20, 0x30, 0x31, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x73, 0x5b, - 0x38, 0x5d, 0x20, 0x3d, 0x20, 0x73, 0x5b, 0x31, 0x33, 0x5d, 0x20, 0x3d, - 0x20, 0x73, 0x5b, 0x31, 0x38, 0x5d, 0x20, 0x3d, 0x20, 0x73, 0x5b, 0x32, - 0x33, 0x5d, 0x20, 0x3d, 0x20, 0x22, 0x2d, 0x22, 0x3b, 0x0a, 0x09, 0x09, - 0x09, 0x09, 0x09, 0x76, 0x61, 0x72, 0x20, 0x75, 0x75, 0x69, 0x64, 0x20, - 0x3d, 0x20, 0x73, 0x2e, 0x6a, 0x6f, 0x69, 0x6e, 0x28, 0x22, 0x22, 0x29, - 0x3b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, - 0x6e, 0x20, 0x75, 0x75, 0x69, 0x64, 0x3b, 0x0a, 0x09, 0x09, 0x09, 0x09, - 0x7d, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x74, - 0x68, 0x69, 0x73, 0x2e, 0x6c, 0x6f, 0x6e, 0x67, 0x70, 0x6f, 0x6c, 0x6c, - 0x20, 0x3d, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, - 0x29, 0x20, 0x7b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x73, 0x65, 0x6c, - 0x66, 0x2e, 0x63, 0x6f, 0x6d, 0x65, 0x74, 0x50, 0x6f, 0x6c, 0x6c, 0x2e, - 0x6f, 0x6e, 0x72, 0x65, 0x61, 0x64, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, - 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x20, 0x3d, 0x20, 0x66, 0x75, 0x6e, - 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x29, 0x20, 0x7b, 0x0a, 0x09, 0x09, - 0x09, 0x09, 0x09, 0x09, 0x69, 0x66, 0x20, 0x28, 0x73, 0x65, 0x6c, 0x66, - 0x2e, 0x63, 0x6f, 0x6d, 0x65, 0x74, 0x50, 0x6f, 0x6c, 0x6c, 0x2e, 0x72, - 0x65, 0x61, 0x64, 0x79, 0x53, 0x74, 0x61, 0x74, 0x65, 0x20, 0x3d, 0x3d, - 0x3d, 0x20, 0x34, 0x29, 0x20, 0x7b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, - 0x09, 0x09, 0x69, 0x66, 0x20, 0x28, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x63, - 0x6f, 0x6d, 0x65, 0x74, 0x50, 0x6f, 0x6c, 0x6c, 0x2e, 0x73, 0x74, 0x61, - 0x74, 0x75, 0x73, 0x20, 0x21, 0x3d, 0x3d, 0x20, 0x32, 0x30, 0x30, 0x29, - 0x20, 0x7b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x73, - 0x65, 0x6c, 0x66, 0x2e, 0x6c, 0x6f, 0x6e, 0x67, 0x70, 0x6f, 0x6c, 0x6c, - 0x28, 0x29, 0x3b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, - 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x3b, 0x0a, 0x09, 0x09, 0x09, 0x09, - 0x09, 0x09, 0x09, 0x7d, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, - 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6f, 0x6e, 0x52, 0x63, 0x76, 0x64, 0x28, - 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x63, 0x6f, 0x6d, 0x65, 0x74, 0x50, 0x6f, - 0x6c, 0x6c, 0x29, 0x3b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, - 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6c, 0x6f, 0x6e, 0x67, 0x70, 0x6f, 0x6c, - 0x6c, 0x28, 0x29, 0x3b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x7d, - 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x7d, 0x3b, 0x0a, 0x09, 0x09, 0x09, - 0x09, 0x09, 0x2f, 0x2f, 0x20, 0x75, 0x73, 0x65, 0x20, 0x74, 0x6f, 0x6b, - 0x65, 0x6e, 0x20, 0x75, 0x6e, 0x74, 0x69, 0x6c, 0x20, 0x77, 0x65, 0x20, - 0x68, 0x61, 0x76, 0x65, 0x20, 0x61, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x65, - 0x78, 0x74, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x73, 0x65, 0x6c, 0x66, - 0x2e, 0x63, 0x6f, 0x6d, 0x65, 0x74, 0x50, 0x6f, 0x6c, 0x6c, 0x2e, 0x6f, - 0x70, 0x65, 0x6e, 0x28, 0x22, 0x47, 0x45, 0x54, 0x22, 0x2c, 0x20, 0x73, - 0x65, 0x6c, 0x66, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x2b, - 0x20, 0x28, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, - 0x20, 0x3f, 0x20, 0x22, 0x3f, 0x22, 0x20, 0x2b, 0x20, 0x73, 0x65, 0x6c, - 0x66, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x20, 0x3a, 0x20, 0x22, 0x22, - 0x29, 0x29, 0x3b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x73, 0x65, 0x6c, - 0x66, 0x2e, 0x63, 0x6f, 0x6d, 0x65, 0x74, 0x50, 0x6f, 0x6c, 0x6c, 0x2e, - 0x73, 0x65, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x48, 0x65, - 0x61, 0x64, 0x65, 0x72, 0x28, 0x27, 0x58, 0x2d, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x65, 0x64, 0x2d, 0x57, 0x69, 0x74, 0x68, 0x27, 0x2c, - 0x20, 0x27, 0x58, 0x4d, 0x4c, 0x48, 0x74, 0x74, 0x70, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x27, 0x29, 0x3b, 0x0a, 0x09, 0x09, 0x09, 0x09, - 0x09, 0x2f, 0x2f, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x63, 0x6f, 0x6d, - 0x65, 0x74, 0x50, 0x6f, 0x6c, 0x6c, 0x2e, 0x73, 0x65, 0x74, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x28, - 0x22, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x22, - 0x2c, 0x20, 0x22, 0x63, 0x6c, 0x6f, 0x73, 0x65, 0x22, 0x29, 0x3b, 0x0a, - 0x09, 0x09, 0x09, 0x09, 0x09, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x63, 0x6f, - 0x6d, 0x65, 0x74, 0x50, 0x6f, 0x6c, 0x6c, 0x2e, 0x73, 0x65, 0x6e, 0x64, - 0x28, 0x6e, 0x75, 0x6c, 0x6c, 0x29, 0x3b, 0x0a, 0x09, 0x09, 0x09, 0x09, - 0x7d, 0x3b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x0a, 0x09, 0x09, 0x09, 0x09, - 0x74, 0x68, 0x69, 0x73, 0x2e, 0x64, 0x69, 0x73, 0x63, 0x6f, 0x6e, 0x6e, - 0x65, 0x63, 0x74, 0x20, 0x3d, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, - 0x6f, 0x6e, 0x28, 0x29, 0x20, 0x7b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, - 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x78, 0x68, 0x72, 0x2e, 0x6f, 0x70, 0x65, - 0x6e, 0x28, 0x22, 0x50, 0x4f, 0x53, 0x54, 0x22, 0x2c, 0x20, 0x73, 0x65, - 0x6c, 0x66, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x2b, 0x20, - 0x28, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x20, - 0x3f, 0x20, 0x22, 0x3f, 0x22, 0x20, 0x2b, 0x20, 0x73, 0x65, 0x6c, 0x66, - 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x20, 0x3a, 0x20, 0x22, 0x22, 0x29, - 0x2c, 0x20, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x29, 0x3b, 0x0a, 0x09, 0x09, - 0x09, 0x09, 0x09, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x78, 0x68, 0x72, 0x2e, - 0x73, 0x65, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x48, 0x65, - 0x61, 0x64, 0x65, 0x72, 0x28, 0x27, 0x58, 0x2d, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x65, 0x64, 0x2d, 0x57, 0x69, 0x74, 0x68, 0x27, 0x2c, - 0x20, 0x27, 0x58, 0x4d, 0x4c, 0x48, 0x74, 0x74, 0x70, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x27, 0x29, 0x3b, 0x0a, 0x09, 0x09, 0x09, 0x09, - 0x09, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x78, 0x68, 0x72, 0x2e, 0x73, 0x65, - 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x48, 0x65, 0x61, 0x64, - 0x65, 0x72, 0x28, 0x27, 0x58, 0x2d, 0x53, 0x43, 0x58, 0x4d, 0x4c, 0x2d, - 0x4e, 0x61, 0x6d, 0x65, 0x27, 0x2c, 0x20, 0x22, 0x64, 0x6f, 0x6e, 0x65, - 0x2e, 0x69, 0x6e, 0x76, 0x6f, 0x6b, 0x65, 0x22, 0x29, 0x3b, 0x0a, 0x09, - 0x09, 0x09, 0x09, 0x09, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x78, 0x68, 0x72, - 0x2e, 0x73, 0x65, 0x6e, 0x64, 0x28, 0x4e, 0x55, 0x4c, 0x4c, 0x29, 0x3b, - 0x0a, 0x09, 0x09, 0x09, 0x09, 0x7d, 0x3b, 0x0a, 0x09, 0x09, 0x09, 0x09, - 0x0a, 0x09, 0x09, 0x09, 0x09, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x70, 0x6f, - 0x73, 0x74, 0x20, 0x3d, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, - 0x6e, 0x28, 0x6e, 0x61, 0x6d, 0x65, 0x2c, 0x20, 0x64, 0x61, 0x74, 0x61, - 0x2c, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, - 0x65, 0x29, 0x20, 0x7b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x73, 0x65, - 0x6c, 0x66, 0x2e, 0x78, 0x68, 0x72, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x28, - 0x22, 0x50, 0x4f, 0x53, 0x54, 0x22, 0x2c, 0x20, 0x73, 0x65, 0x6c, 0x66, - 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x2b, 0x20, 0x28, 0x73, - 0x65, 0x6c, 0x66, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x20, 0x3f, 0x20, - 0x22, 0x3f, 0x22, 0x20, 0x2b, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x71, - 0x75, 0x65, 0x72, 0x79, 0x20, 0x3a, 0x20, 0x22, 0x22, 0x29, 0x29, 0x3b, - 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x78, - 0x68, 0x72, 0x2e, 0x73, 0x65, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x28, 0x27, 0x58, 0x2d, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x65, 0x64, 0x2d, 0x57, 0x69, 0x74, - 0x68, 0x27, 0x2c, 0x20, 0x27, 0x58, 0x4d, 0x4c, 0x48, 0x74, 0x74, 0x70, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x27, 0x29, 0x3b, 0x0a, 0x09, - 0x09, 0x09, 0x09, 0x09, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x78, 0x68, 0x72, - 0x2e, 0x73, 0x65, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x48, - 0x65, 0x61, 0x64, 0x65, 0x72, 0x28, 0x27, 0x58, 0x2d, 0x53, 0x43, 0x58, - 0x4d, 0x4c, 0x2d, 0x4e, 0x61, 0x6d, 0x65, 0x27, 0x2c, 0x20, 0x6e, 0x61, - 0x6d, 0x65, 0x29, 0x3b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x69, 0x66, - 0x20, 0x28, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, - 0x65, 0x29, 0x20, 0x7b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x73, - 0x65, 0x6c, 0x66, 0x2e, 0x78, 0x68, 0x72, 0x2e, 0x73, 0x65, 0x74, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, - 0x28, 0x27, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x54, 0x79, - 0x70, 0x65, 0x27, 0x2c, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, - 0x54, 0x79, 0x70, 0x65, 0x29, 0x3b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, - 0x7d, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x73, 0x65, 0x6c, 0x66, 0x2e, - 0x78, 0x68, 0x72, 0x2e, 0x73, 0x65, 0x6e, 0x64, 0x28, 0x64, 0x61, 0x74, - 0x61, 0x29, 0x3b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x7d, 0x0a, 0x09, 0x09, - 0x09, 0x09, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x2f, 0x2f, 0x20, 0x73, 0x65, - 0x72, 0x69, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x20, 0x61, 0x6e, 0x20, 0x6f, - 0x62, 0x6a, 0x65, 0x63, 0x74, 0x20, 0x74, 0x6f, 0x20, 0x62, 0x65, 0x20, - 0x73, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x74, 0x68, 0x69, - 0x73, 0x2e, 0x73, 0x65, 0x6e, 0x64, 0x20, 0x3d, 0x20, 0x66, 0x75, 0x6e, - 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x61, 0x6d, 0x65, 0x2c, 0x20, - 0x74, 0x68, 0x69, 0x6e, 0x67, 0x29, 0x20, 0x7b, 0x0a, 0x09, 0x09, 0x09, - 0x09, 0x09, 0x76, 0x61, 0x72, 0x20, 0x64, 0x61, 0x74, 0x61, 0x3b, 0x0a, - 0x09, 0x09, 0x09, 0x09, 0x09, 0x2f, 0x2f, 0x20, 0x73, 0x65, 0x65, 0x20, - 0x61, 0x6c, 0x73, 0x6f, 0x3a, 0x20, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, - 0x2f, 0x2f, 0x72, 0x61, 0x77, 0x2e, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, - 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x64, 0x6f, 0x75, 0x67, 0x6c, 0x61, 0x73, - 0x63, 0x72, 0x6f, 0x63, 0x6b, 0x66, 0x6f, 0x72, 0x64, 0x2f, 0x4a, 0x53, - 0x4f, 0x4e, 0x2d, 0x6a, 0x73, 0x2f, 0x6d, 0x61, 0x73, 0x74, 0x65, 0x72, - 0x2f, 0x63, 0x79, 0x63, 0x6c, 0x65, 0x2e, 0x6a, 0x73, 0x0a, 0x09, 0x09, - 0x09, 0x09, 0x09, 0x2f, 0x2f, 0x20, 0x64, 0x69, 0x73, 0x70, 0x61, 0x74, - 0x63, 0x68, 0x20, 0x6f, 0x76, 0x65, 0x72, 0x20, 0x74, 0x68, 0x69, 0x6e, - 0x67, 0x79, 0x20, 0x74, 0x79, 0x70, 0x65, 0x20, 0x68, 0x65, 0x72, 0x65, - 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x69, 0x66, 0x20, 0x28, 0x74, 0x79, - 0x70, 0x65, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x69, 0x6e, 0x67, 0x20, 0x3d, - 0x3d, 0x3d, 0x20, 0x22, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x22, 0x29, - 0x20, 0x7b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x76, 0x61, 0x72, - 0x20, 0x73, 0x65, 0x65, 0x6e, 0x20, 0x3d, 0x20, 0x5b, 0x5d, 0x3b, 0x0a, - 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x2f, 0x2f, 0x20, 0x77, 0x69, 0x6c, - 0x6c, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x77, 0x6f, 0x72, 0x6b, 0x20, 0x6f, - 0x6e, 0x20, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x20, 0x61, 0x73, 0x20, 0x74, - 0x68, 0x69, 0x6e, 0x67, 0x20, 0x69, 0x73, 0x20, 0x63, 0x68, 0x65, 0x63, - 0x6b, 0x65, 0x64, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x63, 0x79, 0x63, 0x6c, - 0x65, 0x73, 0x20, 0x66, 0x69, 0x72, 0x73, 0x74, 0x0a, 0x09, 0x09, 0x09, - 0x09, 0x09, 0x09, 0x64, 0x61, 0x74, 0x61, 0x20, 0x3d, 0x20, 0x4a, 0x53, - 0x4f, 0x4e, 0x2e, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x69, 0x66, 0x79, - 0x28, 0x74, 0x68, 0x69, 0x6e, 0x67, 0x2c, 0x20, 0x66, 0x75, 0x6e, 0x63, - 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6b, 0x65, 0x79, 0x2c, 0x20, 0x76, 0x61, - 0x6c, 0x29, 0x20, 0x7b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, - 0x69, 0x66, 0x20, 0x28, 0x69, 0x73, 0x4e, 0x6f, 0x64, 0x65, 0x28, 0x76, - 0x61, 0x6c, 0x29, 0x29, 0x20, 0x7b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, - 0x09, 0x09, 0x09, 0x2f, 0x2f, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, - 0x20, 0x61, 0x20, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, - 0x20, 0x6f, 0x66, 0x20, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, - 0x65, 0x73, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x72, - 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x7b, 0x0a, 0x09, 0x09, 0x09, 0x09, - 0x09, 0x09, 0x09, 0x09, 0x09, 0x69, 0x64, 0x3a, 0x20, 0x76, 0x61, 0x6c, - 0x2e, 0x69, 0x64, 0x2c, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, - 0x09, 0x09, 0x74, 0x61, 0x67, 0x4e, 0x61, 0x6d, 0x65, 0x3a, 0x20, 0x76, - 0x61, 0x6c, 0x2e, 0x74, 0x61, 0x67, 0x4e, 0x61, 0x6d, 0x65, 0x2c, 0x0a, - 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x6c, 0x6f, 0x63, - 0x61, 0x6c, 0x4e, 0x61, 0x6d, 0x65, 0x3a, 0x20, 0x76, 0x61, 0x6c, 0x2e, - 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x4e, 0x61, 0x6d, 0x65, 0x0a, 0x09, 0x09, - 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x7d, 0x3b, 0x0a, 0x09, 0x09, 0x09, - 0x09, 0x09, 0x09, 0x09, 0x7d, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, - 0x09, 0x69, 0x66, 0x20, 0x28, 0x69, 0x73, 0x57, 0x69, 0x6e, 0x64, 0x6f, - 0x77, 0x28, 0x76, 0x61, 0x6c, 0x29, 0x29, 0x20, 0x7b, 0x0a, 0x09, 0x09, - 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, - 0x3b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x7d, 0x0a, 0x09, - 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x69, 0x66, 0x20, 0x28, 0x74, 0x79, - 0x70, 0x65, 0x6f, 0x66, 0x20, 0x76, 0x61, 0x6c, 0x20, 0x3d, 0x3d, 0x3d, - 0x20, 0x22, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x22, 0x29, 0x20, 0x7b, - 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x69, 0x66, 0x20, - 0x28, 0x73, 0x65, 0x65, 0x6e, 0x2e, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x4f, - 0x66, 0x28, 0x76, 0x61, 0x6c, 0x29, 0x20, 0x3e, 0x3d, 0x20, 0x30, 0x29, - 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x72, 0x65, - 0x74, 0x75, 0x72, 0x6e, 0x3b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, - 0x09, 0x09, 0x73, 0x65, 0x65, 0x6e, 0x2e, 0x70, 0x75, 0x73, 0x68, 0x28, - 0x76, 0x61, 0x6c, 0x29, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, - 0x7d, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x72, 0x65, 0x74, - 0x75, 0x72, 0x6e, 0x20, 0x76, 0x61, 0x6c, 0x0a, 0x09, 0x09, 0x09, 0x09, - 0x09, 0x09, 0x7d, 0x29, 0x3b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x7d, - 0x20, 0x65, 0x6c, 0x73, 0x65, 0x20, 0x7b, 0x0a, 0x09, 0x09, 0x09, 0x09, - 0x09, 0x09, 0x64, 0x61, 0x74, 0x61, 0x20, 0x3d, 0x20, 0x74, 0x68, 0x69, - 0x6e, 0x67, 0x3b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x7d, 0x0a, 0x09, - 0x09, 0x09, 0x09, 0x09, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x70, 0x6f, 0x73, - 0x74, 0x28, 0x6e, 0x61, 0x6d, 0x65, 0x2c, 0x20, 0x64, 0x61, 0x74, 0x61, - 0x2c, 0x20, 0x22, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x2f, 0x6a, 0x73, 0x6f, 0x6e, 0x22, 0x29, 0x3b, 0x0a, 0x09, - 0x09, 0x09, 0x09, 0x7d, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x0a, 0x09, 0x09, - 0x09, 0x09, 0x2f, 0x2f, 0x20, 0x68, 0x65, 0x6c, 0x70, 0x65, 0x72, 0x20, - 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x74, 0x6f, 0x20, - 0x64, 0x65, 0x74, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x65, 0x20, 0x77, 0x68, - 0x65, 0x74, 0x68, 0x65, 0x72, 0x20, 0x73, 0x6f, 0x6d, 0x65, 0x74, 0x68, - 0x69, 0x6e, 0x67, 0x20, 0x69, 0x73, 0x20, 0x61, 0x20, 0x68, 0x74, 0x6d, - 0x6c, 0x20, 0x6e, 0x6f, 0x64, 0x65, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x76, - 0x61, 0x72, 0x20, 0x69, 0x73, 0x4e, 0x6f, 0x64, 0x65, 0x20, 0x3d, 0x20, - 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6f, 0x29, 0x7b, - 0x0a, 0x09, 0x09, 0x09, 0x09, 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, - 0x6e, 0x20, 0x28, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x20, 0x20, 0x20, 0x20, - 0x74, 0x79, 0x70, 0x65, 0x6f, 0x66, 0x20, 0x4e, 0x6f, 0x64, 0x65, 0x20, - 0x3d, 0x3d, 0x3d, 0x20, 0x22, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x22, - 0x20, 0x3f, 0x20, 0x6f, 0x20, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, - 0x65, 0x6f, 0x66, 0x20, 0x4e, 0x6f, 0x64, 0x65, 0x20, 0x3a, 0x20, 0x0a, - 0x09, 0x09, 0x09, 0x09, 0x20, 0x20, 0x20, 0x20, 0x6f, 0x20, 0x26, 0x26, - 0x20, 0x74, 0x79, 0x70, 0x65, 0x6f, 0x66, 0x20, 0x6f, 0x20, 0x3d, 0x3d, - 0x3d, 0x20, 0x22, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x22, 0x20, 0x26, - 0x26, 0x20, 0x74, 0x79, 0x70, 0x65, 0x6f, 0x66, 0x20, 0x6f, 0x2e, 0x6e, - 0x6f, 0x64, 0x65, 0x54, 0x79, 0x70, 0x65, 0x20, 0x3d, 0x3d, 0x3d, 0x20, - 0x22, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x22, 0x20, 0x26, 0x26, 0x20, - 0x74, 0x79, 0x70, 0x65, 0x6f, 0x66, 0x20, 0x6f, 0x2e, 0x6e, 0x6f, 0x64, - 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x3d, 0x3d, 0x3d, 0x22, 0x73, 0x74, 0x72, - 0x69, 0x6e, 0x67, 0x22, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x20, 0x20, 0x29, - 0x3b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x7d, 0x0a, 0x0a, 0x09, 0x09, 0x09, - 0x09, 0x2f, 0x2f, 0x20, 0x68, 0x65, 0x6c, 0x70, 0x65, 0x72, 0x20, 0x66, - 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x74, 0x6f, 0x20, 0x64, - 0x65, 0x74, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x65, 0x20, 0x77, 0x68, 0x65, - 0x74, 0x68, 0x65, 0x72, 0x20, 0x73, 0x6f, 0x6d, 0x65, 0x74, 0x68, 0x69, - 0x6e, 0x67, 0x20, 0x69, 0x73, 0x20, 0x61, 0x20, 0x77, 0x69, 0x6e, 0x64, - 0x6f, 0x77, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x76, 0x61, 0x72, 0x20, 0x69, - 0x73, 0x57, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x20, 0x3d, 0x20, 0x66, 0x75, - 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6f, 0x29, 0x7b, 0x0a, 0x09, - 0x09, 0x09, 0x09, 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, - 0x28, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x20, 0x20, 0x20, 0x20, 0x74, 0x79, - 0x70, 0x65, 0x6f, 0x66, 0x20, 0x57, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x20, - 0x3d, 0x3d, 0x3d, 0x20, 0x22, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x22, - 0x20, 0x3f, 0x20, 0x6f, 0x20, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, - 0x65, 0x6f, 0x66, 0x20, 0x57, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x20, 0x3a, - 0x20, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x20, 0x20, 0x20, 0x20, 0x6f, 0x20, - 0x26, 0x26, 0x20, 0x74, 0x79, 0x70, 0x65, 0x6f, 0x66, 0x20, 0x6f, 0x20, - 0x3d, 0x3d, 0x3d, 0x20, 0x22, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x22, - 0x20, 0x26, 0x26, 0x20, 0x74, 0x79, 0x70, 0x65, 0x6f, 0x66, 0x20, 0x6f, - 0x2e, 0x6d, 0x65, 0x6e, 0x75, 0x62, 0x61, 0x72, 0x20, 0x3d, 0x3d, 0x3d, - 0x20, 0x22, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x22, 0x0a, 0x09, 0x09, - 0x09, 0x09, 0x20, 0x20, 0x29, 0x3b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x7d, - 0x0a, 0x09, 0x09, 0x09, 0x09, 0x0a, 0x09, 0x09, 0x09, 0x7d, 0x0a, 0x09, - 0x09, 0x0a, 0x09, 0x09, 0x3c, 0x2f, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, - 0x3e, 0x0a, 0x09, 0x09, 0x0a, 0x09, 0x09, 0x3c, 0x73, 0x63, 0x72, 0x69, - 0x70, 0x74, 0x20, 0x74, 0x79, 0x70, 0x65, 0x3d, 0x22, 0x74, 0x65, 0x78, - 0x74, 0x2f, 0x6a, 0x61, 0x76, 0x61, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, - 0x22, 0x3e, 0x0a, 0x09, 0x09, 0x09, 0x64, 0x6f, 0x6d, 0x4c, 0x6f, 0x61, - 0x64, 0x65, 0x64, 0x28, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, - 0x20, 0x28, 0x29, 0x20, 0x7b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x73, 0x63, - 0x78, 0x6d, 0x6c, 0x20, 0x3d, 0x20, 0x6e, 0x65, 0x77, 0x20, 0x43, 0x6f, - 0x6d, 0x65, 0x74, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x28, 0x7b, - 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x2f, 0x2f, 0x65, 0x6c, 0x65, 0x6d, - 0x65, 0x6e, 0x74, 0x3a, 0x20, 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, - 0x74, 0x2e, 0x67, 0x65, 0x74, 0x45, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, - 0x42, 0x79, 0x49, 0x64, 0x28, 0x22, 0x24, 0x7b, 0x73, 0x63, 0x78, 0x6d, - 0x6c, 0x2e, 0x69, 0x6e, 0x76, 0x6f, 0x6b, 0x65, 0x49, 0x64, 0x7d, 0x22, - 0x29, 0x2c, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x73, 0x65, 0x72, 0x76, - 0x65, 0x72, 0x3a, 0x20, 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, - 0x2e, 0x55, 0x52, 0x4c, 0x2c, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x6f, - 0x6e, 0x52, 0x63, 0x76, 0x64, 0x20, 0x3a, 0x20, 0x66, 0x75, 0x6e, 0x63, - 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x64, 0x61, 0x74, 0x61, 0x29, 0x20, 0x7b, - 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x69, 0x66, 0x20, 0x28, 0x64, - 0x61, 0x74, 0x61, 0x2e, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x58, 0x4d, 0x4c, 0x29, 0x20, 0x7b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, - 0x09, 0x09, 0x76, 0x61, 0x72, 0x20, 0x74, 0x79, 0x70, 0x65, 0x20, 0x3d, - 0x20, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x67, 0x65, 0x74, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x28, - 0x22, 0x58, 0x2d, 0x53, 0x43, 0x58, 0x4d, 0x4c, 0x2d, 0x54, 0x79, 0x70, - 0x65, 0x22, 0x29, 0x20, 0x7c, 0x7c, 0x20, 0x22, 0x72, 0x65, 0x70, 0x6c, - 0x61, 0x63, 0x65, 0x63, 0x68, 0x69, 0x6c, 0x64, 0x72, 0x65, 0x6e, 0x22, - 0x3b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x76, 0x61, 0x72, - 0x20, 0x64, 0x6f, 0x6d, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x20, 0x3d, - 0x20, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x67, 0x65, 0x74, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x28, - 0x22, 0x58, 0x2d, 0x53, 0x43, 0x58, 0x4d, 0x4c, 0x2d, 0x58, 0x50, 0x61, - 0x74, 0x68, 0x22, 0x29, 0x20, 0x7c, 0x7c, 0x20, 0x22, 0x2f, 0x68, 0x74, - 0x6d, 0x6c, 0x2f, 0x62, 0x6f, 0x64, 0x79, 0x22, 0x3b, 0x0a, 0x09, 0x09, - 0x09, 0x09, 0x09, 0x09, 0x09, 0x76, 0x61, 0x72, 0x20, 0x64, 0x6f, 0x6d, - 0x41, 0x74, 0x74, 0x72, 0x20, 0x3d, 0x20, 0x64, 0x61, 0x74, 0x61, 0x2e, - 0x67, 0x65, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x48, - 0x65, 0x61, 0x64, 0x65, 0x72, 0x28, 0x22, 0x58, 0x2d, 0x53, 0x43, 0x58, - 0x4d, 0x4c, 0x2d, 0x41, 0x74, 0x74, 0x72, 0x22, 0x29, 0x3b, 0x0a, 0x09, - 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x76, 0x61, 0x72, 0x20, 0x72, 0x65, - 0x73, 0x75, 0x6c, 0x74, 0x20, 0x3d, 0x20, 0x64, 0x6f, 0x63, 0x75, 0x6d, - 0x65, 0x6e, 0x74, 0x2e, 0x65, 0x76, 0x61, 0x6c, 0x75, 0x61, 0x74, 0x65, - 0x28, 0x64, 0x6f, 0x6d, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x2c, 0x20, - 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x2c, 0x20, 0x6e, 0x75, - 0x6c, 0x6c, 0x2c, 0x20, 0x58, 0x50, 0x61, 0x74, 0x68, 0x52, 0x65, 0x73, - 0x75, 0x6c, 0x74, 0x2e, 0x4f, 0x52, 0x44, 0x45, 0x52, 0x45, 0x44, 0x5f, - 0x4e, 0x4f, 0x44, 0x45, 0x5f, 0x53, 0x4e, 0x41, 0x50, 0x53, 0x48, 0x4f, - 0x54, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x2c, 0x20, 0x6e, 0x75, 0x6c, 0x6c, - 0x29, 0x3b, 0x0a, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x66, - 0x6f, 0x72, 0x20, 0x28, 0x76, 0x61, 0x72, 0x20, 0x69, 0x20, 0x3d, 0x20, - 0x30, 0x2c, 0x20, 0x6c, 0x20, 0x3d, 0x20, 0x72, 0x65, 0x73, 0x75, 0x6c, - 0x74, 0x2e, 0x73, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x4c, 0x65, - 0x6e, 0x67, 0x74, 0x68, 0x3b, 0x20, 0x69, 0x20, 0x3c, 0x20, 0x6c, 0x3b, - 0x20, 0x69, 0x2b, 0x2b, 0x29, 0x20, 0x7b, 0x0a, 0x09, 0x09, 0x09, 0x09, - 0x09, 0x09, 0x09, 0x09, 0x76, 0x61, 0x72, 0x20, 0x69, 0x74, 0x65, 0x6d, - 0x20, 0x3d, 0x20, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x2e, 0x73, 0x6e, - 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x49, 0x74, 0x65, 0x6d, 0x28, 0x69, - 0x29, 0x3b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x76, - 0x61, 0x72, 0x20, 0x6e, 0x6f, 0x64, 0x65, 0x20, 0x3d, 0x20, 0x64, 0x6f, - 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x69, 0x6d, 0x70, 0x6f, 0x72, - 0x74, 0x4e, 0x6f, 0x64, 0x65, 0x28, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x72, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x58, 0x4d, 0x4c, 0x2e, 0x66, - 0x69, 0x72, 0x73, 0x74, 0x43, 0x68, 0x69, 0x6c, 0x64, 0x2c, 0x20, 0x74, - 0x72, 0x75, 0x65, 0x29, 0x3b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, - 0x09, 0x09, 0x73, 0x77, 0x69, 0x74, 0x63, 0x68, 0x20, 0x28, 0x74, 0x79, - 0x70, 0x65, 0x29, 0x20, 0x7b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, - 0x09, 0x09, 0x09, 0x63, 0x61, 0x73, 0x65, 0x20, 0x22, 0x66, 0x69, 0x72, - 0x73, 0x74, 0x63, 0x68, 0x69, 0x6c, 0x64, 0x22, 0x3a, 0x0a, 0x09, 0x09, - 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x69, 0x74, 0x65, 0x6d, - 0x2e, 0x69, 0x6e, 0x73, 0x65, 0x72, 0x74, 0x42, 0x65, 0x66, 0x6f, 0x72, - 0x65, 0x28, 0x6e, 0x6f, 0x64, 0x65, 0x2c, 0x20, 0x69, 0x74, 0x65, 0x6d, - 0x2e, 0x66, 0x69, 0x72, 0x73, 0x74, 0x43, 0x68, 0x69, 0x6c, 0x64, 0x29, - 0x3b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x62, - 0x72, 0x65, 0x61, 0x6b, 0x3b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, - 0x09, 0x09, 0x09, 0x63, 0x61, 0x73, 0x65, 0x20, 0x22, 0x6c, 0x61, 0x73, - 0x74, 0x63, 0x68, 0x69, 0x6c, 0x64, 0x22, 0x3a, 0x0a, 0x09, 0x09, 0x09, - 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x69, 0x74, 0x65, 0x6d, 0x2e, - 0x61, 0x70, 0x70, 0x65, 0x6e, 0x64, 0x43, 0x68, 0x69, 0x6c, 0x64, 0x28, - 0x6e, 0x6f, 0x64, 0x65, 0x29, 0x3b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, - 0x09, 0x09, 0x09, 0x09, 0x62, 0x72, 0x65, 0x61, 0x6b, 0x3b, 0x0a, 0x09, - 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x63, 0x61, 0x73, 0x65, - 0x20, 0x22, 0x70, 0x72, 0x65, 0x76, 0x69, 0x6f, 0x75, 0x73, 0x73, 0x69, - 0x62, 0x6c, 0x69, 0x6e, 0x67, 0x22, 0x3a, 0x0a, 0x09, 0x09, 0x09, 0x09, - 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x69, 0x74, 0x65, 0x6d, 0x2e, 0x70, - 0x61, 0x72, 0x65, 0x6e, 0x74, 0x4e, 0x6f, 0x64, 0x65, 0x2e, 0x69, 0x6e, - 0x73, 0x65, 0x72, 0x74, 0x42, 0x65, 0x66, 0x6f, 0x72, 0x65, 0x28, 0x6e, - 0x6f, 0x64, 0x65, 0x2c, 0x20, 0x69, 0x74, 0x65, 0x6d, 0x29, 0x3b, 0x0a, - 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x62, 0x72, 0x65, - 0x61, 0x6b, 0x3b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, - 0x09, 0x63, 0x61, 0x73, 0x65, 0x20, 0x22, 0x6e, 0x65, 0x78, 0x74, 0x73, - 0x69, 0x62, 0x6c, 0x69, 0x6e, 0x67, 0x22, 0x3a, 0x0a, 0x09, 0x09, 0x09, - 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x69, 0x74, 0x65, 0x6d, 0x2e, - 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x4e, 0x6f, 0x64, 0x65, 0x2e, 0x69, - 0x6e, 0x73, 0x65, 0x72, 0x74, 0x42, 0x65, 0x66, 0x6f, 0x72, 0x65, 0x28, - 0x6e, 0x6f, 0x64, 0x65, 0x2c, 0x20, 0x69, 0x74, 0x65, 0x6d, 0x2e, 0x6e, - 0x65, 0x78, 0x74, 0x53, 0x69, 0x62, 0x6c, 0x69, 0x6e, 0x67, 0x29, 0x3b, - 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x62, 0x72, - 0x65, 0x61, 0x6b, 0x3b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, - 0x09, 0x09, 0x63, 0x61, 0x73, 0x65, 0x20, 0x22, 0x72, 0x65, 0x70, 0x6c, - 0x61, 0x63, 0x65, 0x22, 0x3a, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, - 0x09, 0x09, 0x09, 0x09, 0x69, 0x74, 0x65, 0x6d, 0x2e, 0x70, 0x61, 0x72, - 0x65, 0x6e, 0x74, 0x4e, 0x6f, 0x64, 0x65, 0x2e, 0x72, 0x65, 0x70, 0x6c, - 0x61, 0x63, 0x65, 0x43, 0x68, 0x69, 0x6c, 0x64, 0x28, 0x6e, 0x6f, 0x64, - 0x65, 0x2c, 0x20, 0x69, 0x74, 0x65, 0x6d, 0x29, 0x3b, 0x0a, 0x09, 0x09, - 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x62, 0x72, 0x65, 0x61, 0x6b, - 0x3b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x63, - 0x61, 0x73, 0x65, 0x20, 0x22, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x22, - 0x3a, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, - 0x69, 0x74, 0x65, 0x6d, 0x2e, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x4e, - 0x6f, 0x64, 0x65, 0x2e, 0x72, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x43, 0x68, - 0x69, 0x6c, 0x64, 0x28, 0x69, 0x74, 0x65, 0x6d, 0x29, 0x3b, 0x0a, 0x09, - 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x62, 0x72, 0x65, 0x61, - 0x6b, 0x3b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, - 0x63, 0x61, 0x73, 0x65, 0x20, 0x22, 0x61, 0x64, 0x64, 0x61, 0x74, 0x74, - 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x22, 0x3a, 0x0a, 0x09, 0x09, 0x09, - 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x69, 0x74, 0x65, 0x6d, 0x2e, - 0x73, 0x65, 0x74, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, - 0x28, 0x64, 0x6f, 0x6d, 0x41, 0x74, 0x74, 0x72, 0x2c, 0x20, 0x6e, 0x6f, - 0x64, 0x65, 0x29, 0x3b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, - 0x09, 0x09, 0x62, 0x72, 0x65, 0x61, 0x6b, 0x3b, 0x0a, 0x09, 0x09, 0x09, - 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x63, 0x61, 0x73, 0x65, 0x20, 0x22, - 0x72, 0x65, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x63, 0x68, 0x69, 0x6c, 0x64, - 0x72, 0x65, 0x6e, 0x22, 0x3a, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, - 0x09, 0x09, 0x09, 0x09, 0x77, 0x68, 0x69, 0x6c, 0x65, 0x28, 0x69, 0x74, - 0x65, 0x6d, 0x2e, 0x68, 0x61, 0x73, 0x43, 0x68, 0x69, 0x6c, 0x64, 0x4e, - 0x6f, 0x64, 0x65, 0x73, 0x28, 0x29, 0x29, 0x20, 0x7b, 0x0a, 0x09, 0x09, - 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x69, 0x74, 0x65, - 0x6d, 0x2e, 0x72, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x43, 0x68, 0x69, 0x6c, - 0x64, 0x28, 0x69, 0x74, 0x65, 0x6d, 0x2e, 0x66, 0x69, 0x72, 0x73, 0x74, - 0x43, 0x68, 0x69, 0x6c, 0x64, 0x29, 0x3b, 0x0a, 0x09, 0x09, 0x09, 0x09, - 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x7d, 0x0a, 0x09, 0x09, 0x09, 0x09, - 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x69, 0x74, 0x65, 0x6d, 0x2e, 0x61, - 0x70, 0x70, 0x65, 0x6e, 0x64, 0x43, 0x68, 0x69, 0x6c, 0x64, 0x28, 0x6e, - 0x6f, 0x64, 0x65, 0x29, 0x3b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, - 0x09, 0x09, 0x09, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x3a, 0x0a, - 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x62, 0x72, 0x65, - 0x61, 0x6b, 0x3b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, - 0x7d, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x7d, 0x0a, 0x09, - 0x09, 0x09, 0x09, 0x09, 0x09, 0x7d, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, - 0x7d, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x7d, 0x29, 0x3b, 0x0a, 0x09, 0x09, - 0x09, 0x09, 0x73, 0x63, 0x78, 0x6d, 0x6c, 0x2e, 0x6c, 0x6f, 0x6e, 0x67, - 0x70, 0x6f, 0x6c, 0x6c, 0x28, 0x29, 0x3b, 0x0a, 0x09, 0x09, 0x09, 0x09, - 0x5f, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x20, 0x3d, 0x20, 0x73, 0x63, - 0x78, 0x6d, 0x6c, 0x3b, 0x0a, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x77, 0x69, - 0x6e, 0x64, 0x6f, 0x77, 0x2e, 0x6f, 0x6e, 0x62, 0x65, 0x66, 0x6f, 0x72, - 0x65, 0x75, 0x6e, 0x6c, 0x6f, 0x61, 0x64, 0x20, 0x3d, 0x20, 0x66, 0x75, - 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x65, 0x29, 0x20, 0x7b, - 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x73, 0x63, 0x78, 0x6d, 0x6c, 0x2e, - 0x64, 0x69, 0x73, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x28, 0x29, - 0x3b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x2f, 0x2f, 0x20, 0x72, 0x65, - 0x74, 0x75, 0x72, 0x6e, 0x20, 0x27, 0x59, 0x6f, 0x75, 0x20, 0x68, 0x61, - 0x76, 0x65, 0x20, 0x75, 0x6e, 0x73, 0x61, 0x76, 0x65, 0x64, 0x20, 0x63, - 0x68, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x21, 0x27, 0x3b, 0x0a, 0x09, 0x09, - 0x09, 0x09, 0x7d, 0x3b, 0x0a, 0x09, 0x09, 0x09, 0x7d, 0x29, 0x3b, 0x0a, - 0x09, 0x09, 0x3c, 0x2f, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x3e, 0x0a, - 0x0a, 0x09, 0x3c, 0x2f, 0x68, 0x65, 0x61, 0x64, 0x3e, 0x0a, 0x09, 0x3c, - 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x3c, 0x2f, 0x62, 0x6f, 0x64, 0x79, 0x3e, - 0x0a, 0x3c, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x3e, 0x0a + 0x3c, 0x68, 0x74, 0x6d, 0x6c, 0x20, 0x78, 0x6d, 0x6c, 0x6e, 0x73, 0x3d, + 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, + 0x77, 0x33, 0x2e, 0x6f, 0x72, 0x67, 0x2f, 0x31, 0x39, 0x39, 0x39, 0x2f, + 0x78, 0x68, 0x74, 0x6d, 0x6c, 0x22, 0x3e, 0x0a, 0x09, 0x3c, 0x68, 0x65, + 0x61, 0x64, 0x3e, 0x0a, 0x09, 0x09, 0x3c, 0x6d, 0x65, 0x74, 0x61, 0x20, + 0x68, 0x74, 0x74, 0x70, 0x2d, 0x65, 0x71, 0x75, 0x69, 0x76, 0x3d, 0x22, + 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x54, 0x79, 0x70, 0x65, + 0x22, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x3d, 0x22, 0x74, + 0x65, 0x78, 0x74, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x3b, 0x63, 0x68, 0x61, + 0x72, 0x73, 0x65, 0x74, 0x3d, 0x75, 0x74, 0x66, 0x2d, 0x38, 0x22, 0x20, + 0x2f, 0x3e, 0x0a, 0x0a, 0x09, 0x09, 0x3c, 0x21, 0x2d, 0x2d, 0x20, 0x47, + 0x65, 0x74, 0x20, 0x64, 0x6f, 0x6d, 0x4c, 0x6f, 0x61, 0x64, 0x65, 0x64, + 0x20, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x20, 0x61, 0x63, 0x72, 0x6f, 0x73, + 0x73, 0x20, 0x62, 0x72, 0x6f, 0x77, 0x73, 0x65, 0x72, 0x73, 0x20, 0x2d, + 0x2d, 0x3e, 0x0a, 0x09, 0x09, 0x3c, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, + 0x20, 0x74, 0x79, 0x70, 0x65, 0x3d, 0x22, 0x74, 0x65, 0x78, 0x74, 0x2f, + 0x6a, 0x61, 0x76, 0x61, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x22, 0x3e, + 0x0a, 0x09, 0x09, 0x09, 0x2f, 0x2f, 0x20, 0x73, 0x65, 0x65, 0x20, 0x68, + 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x6f, + 0x76, 0x65, 0x72, 0x66, 0x6c, 0x6f, 0x77, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x31, 0x32, + 0x30, 0x36, 0x39, 0x33, 0x37, 0x2f, 0x6a, 0x61, 0x76, 0x61, 0x73, 0x63, + 0x72, 0x69, 0x70, 0x74, 0x2d, 0x64, 0x6f, 0x6d, 0x72, 0x65, 0x61, 0x64, + 0x79, 0x0a, 0x09, 0x09, 0x09, 0x76, 0x61, 0x72, 0x20, 0x64, 0x6f, 0x6d, + 0x4c, 0x6f, 0x61, 0x64, 0x65, 0x64, 0x20, 0x3d, 0x20, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x63, 0x61, 0x6c, 0x6c, 0x62, 0x61, + 0x63, 0x6b, 0x29, 0x20, 0x7b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x2f, 0x2a, + 0x20, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x20, 0x45, 0x78, + 0x70, 0x6c, 0x6f, 0x72, 0x65, 0x72, 0x20, 0x2a, 0x2f, 0x0a, 0x09, 0x09, + 0x09, 0x09, 0x2f, 0x2a, 0x40, 0x63, 0x63, 0x5f, 0x6f, 0x6e, 0x0a, 0x09, + 0x09, 0x09, 0x09, 0x40, 0x69, 0x66, 0x20, 0x28, 0x40, 0x5f, 0x77, 0x69, + 0x6e, 0x33, 0x32, 0x20, 0x7c, 0x7c, 0x20, 0x40, 0x5f, 0x77, 0x69, 0x6e, + 0x36, 0x34, 0x29, 0x09, 0x09, 0x09, 0x09, 0x09, 0x0a, 0x09, 0x09, 0x09, + 0x09, 0x09, 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x77, + 0x72, 0x69, 0x74, 0x65, 0x28, 0x27, 0x3c, 0x73, 0x63, 0x72, 0x69, 0x70, + 0x74, 0x20, 0x69, 0x64, 0x3d, 0x22, 0x69, 0x65, 0x53, 0x63, 0x72, 0x69, + 0x70, 0x74, 0x4c, 0x6f, 0x61, 0x64, 0x22, 0x20, 0x64, 0x65, 0x66, 0x65, + 0x72, 0x20, 0x73, 0x72, 0x63, 0x3d, 0x22, 0x2f, 0x2f, 0x3a, 0x22, 0x3e, + 0x3c, 0x5c, 0x2f, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x3e, 0x27, 0x29, + 0x3b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x64, 0x6f, 0x63, 0x75, 0x6d, + 0x65, 0x6e, 0x74, 0x2e, 0x67, 0x65, 0x74, 0x45, 0x6c, 0x65, 0x6d, 0x65, + 0x6e, 0x74, 0x42, 0x79, 0x49, 0x64, 0x28, 0x27, 0x69, 0x65, 0x53, 0x63, + 0x72, 0x69, 0x70, 0x74, 0x4c, 0x6f, 0x61, 0x64, 0x27, 0x29, 0x2e, 0x6f, + 0x6e, 0x72, 0x65, 0x61, 0x64, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, 0x63, + 0x68, 0x61, 0x6e, 0x67, 0x65, 0x20, 0x3d, 0x20, 0x66, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x29, 0x20, 0x7b, 0x0a, 0x09, 0x09, 0x09, + 0x09, 0x09, 0x09, 0x69, 0x66, 0x20, 0x28, 0x74, 0x68, 0x69, 0x73, 0x2e, + 0x72, 0x65, 0x61, 0x64, 0x79, 0x53, 0x74, 0x61, 0x74, 0x65, 0x20, 0x3d, + 0x3d, 0x20, 0x27, 0x63, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x27, + 0x29, 0x20, 0x7b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x76, + 0x61, 0x72, 0x20, 0x68, 0x65, 0x61, 0x64, 0x3d, 0x20, 0x64, 0x6f, 0x63, + 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x67, 0x65, 0x74, 0x45, 0x6c, 0x65, + 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x42, 0x79, 0x54, 0x61, 0x67, 0x4e, 0x61, + 0x6d, 0x65, 0x28, 0x27, 0x68, 0x65, 0x61, 0x64, 0x27, 0x29, 0x5b, 0x30, + 0x5d, 0x3b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x76, 0x61, + 0x72, 0x20, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x3d, 0x20, 0x64, 0x6f, + 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x63, 0x72, 0x65, 0x61, 0x74, + 0x65, 0x45, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x28, 0x27, 0x73, 0x63, + 0x72, 0x69, 0x70, 0x74, 0x27, 0x29, 0x3b, 0x0a, 0x09, 0x09, 0x09, 0x09, + 0x09, 0x09, 0x09, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x2e, 0x74, 0x79, + 0x70, 0x65, 0x3d, 0x20, 0x27, 0x74, 0x65, 0x78, 0x74, 0x2f, 0x6a, 0x61, + 0x76, 0x61, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x27, 0x3b, 0x0a, 0x09, + 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, + 0x2e, 0x73, 0x72, 0x63, 0x3d, 0x20, 0x27, 0x68, 0x74, 0x74, 0x70, 0x3a, + 0x2f, 0x2f, 0x77, 0x69, 0x63, 0x6b, 0x65, 0x64, 0x2d, 0x67, 0x6f, 0x6f, + 0x64, 0x2d, 0x78, 0x70, 0x61, 0x74, 0x68, 0x2e, 0x67, 0x6f, 0x6f, 0x67, + 0x6c, 0x65, 0x63, 0x6f, 0x64, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x66, + 0x69, 0x6c, 0x65, 0x73, 0x2f, 0x77, 0x67, 0x78, 0x70, 0x61, 0x74, 0x68, + 0x2e, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x2e, 0x6a, 0x73, 0x27, + 0x3b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x68, 0x65, 0x61, + 0x64, 0x2e, 0x61, 0x70, 0x70, 0x65, 0x6e, 0x64, 0x43, 0x68, 0x69, 0x6c, + 0x64, 0x28, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x29, 0x3b, 0x0a, 0x09, + 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x77, 0x67, 0x78, 0x70, 0x61, 0x74, + 0x68, 0x2e, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x28, 0x29, 0x3b, + 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x0a, 0x09, 0x09, 0x09, + 0x09, 0x09, 0x09, 0x09, 0x2f, 0x2f, 0x20, 0x73, 0x65, 0x65, 0x20, 0x68, + 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x6f, + 0x76, 0x65, 0x72, 0x66, 0x6c, 0x6f, 0x77, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x31, 0x38, + 0x31, 0x31, 0x31, 0x31, 0x36, 0x2f, 0x69, 0x65, 0x2d, 0x73, 0x75, 0x70, + 0x70, 0x6f, 0x72, 0x74, 0x2d, 0x66, 0x6f, 0x72, 0x2d, 0x64, 0x6f, 0x6d, + 0x2d, 0x69, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x6e, 0x6f, 0x64, 0x65, 0x0a, + 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x64, 0x6f, 0x63, 0x75, 0x6d, + 0x65, 0x6e, 0x74, 0x2e, 0x69, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x4e, 0x6f, + 0x64, 0x65, 0x20, 0x3d, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x28, 0x6e, 0x6f, 0x64, 0x65, 0x2c, 0x20, 0x61, 0x6c, 0x6c, 0x43, + 0x68, 0x69, 0x6c, 0x64, 0x72, 0x65, 0x6e, 0x29, 0x20, 0x7b, 0x0a, 0x09, + 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x20, 0x20, 0x73, 0x77, 0x69, 0x74, + 0x63, 0x68, 0x20, 0x28, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x6e, 0x6f, 0x64, + 0x65, 0x54, 0x79, 0x70, 0x65, 0x29, 0x20, 0x7b, 0x0a, 0x09, 0x09, 0x09, + 0x09, 0x09, 0x09, 0x09, 0x20, 0x20, 0x20, 0x20, 0x63, 0x61, 0x73, 0x65, + 0x20, 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x45, 0x4c, + 0x45, 0x4d, 0x45, 0x4e, 0x54, 0x5f, 0x4e, 0x4f, 0x44, 0x45, 0x3a, 0x0a, + 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x76, 0x61, 0x72, 0x20, 0x6e, 0x65, 0x77, 0x4e, 0x6f, 0x64, 0x65, + 0x20, 0x3d, 0x20, 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x2e, + 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x45, 0x6c, 0x65, 0x6d, 0x65, 0x6e, + 0x74, 0x4e, 0x53, 0x28, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x6e, 0x61, 0x6d, + 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x55, 0x52, 0x49, 0x2c, 0x20, 0x6e, + 0x6f, 0x64, 0x65, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x4e, 0x61, 0x6d, 0x65, + 0x29, 0x3b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x69, 0x66, 0x28, 0x6e, 0x6f, 0x64, 0x65, 0x2e, + 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x20, 0x26, + 0x26, 0x20, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x69, + 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, + 0x20, 0x3e, 0x20, 0x30, 0x29, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, + 0x09, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x66, 0x6f, 0x72, + 0x28, 0x76, 0x61, 0x72, 0x20, 0x69, 0x20, 0x3d, 0x20, 0x30, 0x2c, 0x20, + 0x69, 0x6c, 0x20, 0x3d, 0x20, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x61, 0x74, + 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x6c, 0x65, 0x6e, + 0x67, 0x74, 0x68, 0x3b, 0x20, 0x69, 0x20, 0x3c, 0x20, 0x69, 0x6c, 0x3b, + 0x20, 0x69, 0x2b, 0x2b, 0x29, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, + 0x09, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6e, + 0x65, 0x77, 0x4e, 0x6f, 0x64, 0x65, 0x2e, 0x73, 0x65, 0x74, 0x41, 0x74, + 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x28, 0x6e, 0x6f, 0x64, 0x65, + 0x2e, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x5b, + 0x69, 0x5d, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x2c, + 0x20, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x67, 0x65, 0x74, 0x41, 0x74, 0x74, + 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x28, 0x6e, 0x6f, 0x64, 0x65, 0x2e, + 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x5b, 0x69, + 0x5d, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x29, 0x29, + 0x3b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x69, 0x66, 0x28, 0x61, 0x6c, 0x6c, 0x43, 0x68, 0x69, + 0x6c, 0x64, 0x72, 0x65, 0x6e, 0x20, 0x26, 0x26, 0x20, 0x6e, 0x6f, 0x64, + 0x65, 0x2e, 0x63, 0x68, 0x69, 0x6c, 0x64, 0x4e, 0x6f, 0x64, 0x65, 0x73, + 0x20, 0x26, 0x26, 0x20, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x63, 0x68, 0x69, + 0x6c, 0x64, 0x4e, 0x6f, 0x64, 0x65, 0x73, 0x2e, 0x6c, 0x65, 0x6e, 0x67, + 0x74, 0x68, 0x20, 0x3e, 0x20, 0x30, 0x29, 0x0a, 0x09, 0x09, 0x09, 0x09, + 0x09, 0x09, 0x09, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x66, + 0x6f, 0x72, 0x28, 0x76, 0x61, 0x72, 0x20, 0x69, 0x20, 0x3d, 0x20, 0x30, + 0x2c, 0x20, 0x69, 0x6c, 0x20, 0x3d, 0x20, 0x6e, 0x6f, 0x64, 0x65, 0x2e, + 0x63, 0x68, 0x69, 0x6c, 0x64, 0x4e, 0x6f, 0x64, 0x65, 0x73, 0x2e, 0x6c, + 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3b, 0x20, 0x69, 0x20, 0x3c, 0x20, 0x69, + 0x6c, 0x3b, 0x20, 0x69, 0x2b, 0x2b, 0x29, 0x0a, 0x09, 0x09, 0x09, 0x09, + 0x09, 0x09, 0x09, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x6e, 0x65, 0x77, 0x4e, 0x6f, 0x64, 0x65, 0x2e, 0x61, 0x70, 0x70, + 0x65, 0x6e, 0x64, 0x43, 0x68, 0x69, 0x6c, 0x64, 0x28, 0x64, 0x6f, 0x63, + 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x69, 0x6d, 0x70, 0x6f, 0x72, 0x74, + 0x4e, 0x6f, 0x64, 0x65, 0x28, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x63, 0x68, + 0x69, 0x6c, 0x64, 0x4e, 0x6f, 0x64, 0x65, 0x73, 0x5b, 0x69, 0x5d, 0x2c, + 0x20, 0x61, 0x6c, 0x6c, 0x43, 0x68, 0x69, 0x6c, 0x64, 0x72, 0x65, 0x6e, + 0x29, 0x29, 0x3b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, + 0x6e, 0x65, 0x77, 0x4e, 0x6f, 0x64, 0x65, 0x3b, 0x0a, 0x09, 0x09, 0x09, + 0x09, 0x09, 0x09, 0x09, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x62, 0x72, + 0x65, 0x61, 0x6b, 0x3b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, + 0x20, 0x20, 0x20, 0x20, 0x63, 0x61, 0x73, 0x65, 0x20, 0x64, 0x6f, 0x63, + 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x54, 0x45, 0x58, 0x54, 0x5f, 0x4e, + 0x4f, 0x44, 0x45, 0x3a, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, + 0x20, 0x20, 0x20, 0x20, 0x63, 0x61, 0x73, 0x65, 0x20, 0x64, 0x6f, 0x63, + 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x43, 0x44, 0x41, 0x54, 0x41, 0x5f, + 0x53, 0x45, 0x43, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x4e, 0x4f, 0x44, 0x45, + 0x3a, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x20, 0x20, 0x20, + 0x20, 0x63, 0x61, 0x73, 0x65, 0x20, 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, + 0x6e, 0x74, 0x2e, 0x43, 0x4f, 0x4d, 0x4d, 0x45, 0x4e, 0x54, 0x5f, 0x4e, + 0x4f, 0x44, 0x45, 0x3a, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, + 0x20, 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x63, 0x72, + 0x65, 0x61, 0x74, 0x65, 0x54, 0x65, 0x78, 0x74, 0x4e, 0x6f, 0x64, 0x65, + 0x28, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x56, 0x61, + 0x6c, 0x75, 0x65, 0x29, 0x3b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, + 0x09, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x62, 0x72, 0x65, 0x61, 0x6b, + 0x3b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x20, 0x20, 0x7d, + 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x7d, 0x0a, 0x09, 0x09, + 0x09, 0x09, 0x09, 0x09, 0x09, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, + 0x09, 0x63, 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x28, 0x29, 0x3b, + 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x7d, 0x0a, 0x09, 0x09, 0x09, + 0x09, 0x09, 0x7d, 0x3b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x40, 0x65, 0x6e, + 0x64, 0x20, 0x40, 0x2a, 0x2f, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x2f, 0x2a, + 0x20, 0x4d, 0x6f, 0x7a, 0x69, 0x6c, 0x6c, 0x61, 0x2c, 0x20, 0x43, 0x68, + 0x72, 0x6f, 0x6d, 0x65, 0x2c, 0x20, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x20, + 0x2a, 0x2f, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x69, 0x66, 0x20, 0x28, 0x64, + 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x61, 0x64, 0x64, 0x45, + 0x76, 0x65, 0x6e, 0x74, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, + 0x29, 0x20, 0x7b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x64, 0x6f, 0x63, + 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x61, 0x64, 0x64, 0x45, 0x76, 0x65, + 0x6e, 0x74, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x28, 0x27, + 0x44, 0x4f, 0x4d, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x4c, 0x6f, + 0x61, 0x64, 0x65, 0x64, 0x27, 0x2c, 0x20, 0x63, 0x61, 0x6c, 0x6c, 0x62, + 0x61, 0x63, 0x6b, 0x2c, 0x20, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x29, 0x3b, + 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, + 0x3b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x7d, 0x0a, 0x09, 0x09, 0x09, 0x09, + 0x2f, 0x2a, 0x20, 0x53, 0x61, 0x66, 0x61, 0x72, 0x69, 0x2c, 0x20, 0x69, + 0x43, 0x61, 0x62, 0x2c, 0x20, 0x4b, 0x6f, 0x6e, 0x71, 0x75, 0x65, 0x72, + 0x6f, 0x72, 0x20, 0x2a, 0x2f, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x69, 0x66, + 0x20, 0x28, 0x2f, 0x4b, 0x48, 0x54, 0x4d, 0x4c, 0x7c, 0x57, 0x65, 0x62, + 0x4b, 0x69, 0x74, 0x7c, 0x69, 0x43, 0x61, 0x62, 0x2f, 0x69, 0x2e, 0x74, + 0x65, 0x73, 0x74, 0x28, 0x6e, 0x61, 0x76, 0x69, 0x67, 0x61, 0x74, 0x6f, + 0x72, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x29, + 0x29, 0x20, 0x7b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x76, 0x61, 0x72, + 0x20, 0x44, 0x4f, 0x4d, 0x4c, 0x6f, 0x61, 0x64, 0x54, 0x69, 0x6d, 0x65, + 0x72, 0x20, 0x3d, 0x20, 0x73, 0x65, 0x74, 0x49, 0x6e, 0x74, 0x65, 0x72, + 0x76, 0x61, 0x6c, 0x28, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x20, 0x28, 0x29, 0x20, 0x7b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, + 0x69, 0x66, 0x20, 0x28, 0x2f, 0x6c, 0x6f, 0x61, 0x64, 0x65, 0x64, 0x7c, + 0x63, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x2f, 0x69, 0x2e, 0x74, + 0x65, 0x73, 0x74, 0x28, 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, + 0x2e, 0x72, 0x65, 0x61, 0x64, 0x79, 0x53, 0x74, 0x61, 0x74, 0x65, 0x29, + 0x29, 0x20, 0x7b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x63, + 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x28, 0x29, 0x3b, 0x0a, 0x09, + 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x63, 0x6c, 0x65, 0x61, 0x72, 0x49, + 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x28, 0x44, 0x4f, 0x4d, 0x4c, + 0x6f, 0x61, 0x64, 0x54, 0x69, 0x6d, 0x65, 0x72, 0x29, 0x3b, 0x0a, 0x09, + 0x09, 0x09, 0x09, 0x09, 0x09, 0x7d, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, + 0x7d, 0x2c, 0x20, 0x31, 0x30, 0x29, 0x3b, 0x0a, 0x09, 0x09, 0x09, 0x09, + 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x3b, 0x0a, 0x09, 0x09, 0x09, + 0x09, 0x7d, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x2f, 0x2a, 0x20, 0x4f, 0x74, + 0x68, 0x65, 0x72, 0x20, 0x77, 0x65, 0x62, 0x20, 0x62, 0x72, 0x6f, 0x77, + 0x73, 0x65, 0x72, 0x73, 0x20, 0x2a, 0x2f, 0x0a, 0x09, 0x09, 0x09, 0x09, + 0x77, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x2e, 0x6f, 0x6e, 0x6c, 0x6f, 0x61, + 0x64, 0x20, 0x3d, 0x20, 0x63, 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, + 0x3b, 0x0a, 0x09, 0x09, 0x09, 0x7d, 0x3b, 0x0a, 0x09, 0x09, 0x09, 0x3c, + 0x2f, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x3e, 0x0a, 0x0a, 0x09, 0x09, + 0x3c, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x20, 0x74, 0x79, 0x70, 0x65, + 0x3d, 0x22, 0x74, 0x65, 0x78, 0x74, 0x2f, 0x6a, 0x61, 0x76, 0x61, 0x73, + 0x63, 0x72, 0x69, 0x70, 0x74, 0x22, 0x3e, 0x0a, 0x09, 0x09, 0x09, 0x0a, + 0x09, 0x09, 0x09, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, + 0x43, 0x6f, 0x6d, 0x65, 0x74, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, + 0x28, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x29, 0x20, 0x7b, 0x0a, + 0x09, 0x09, 0x09, 0x09, 0x2f, 0x2a, 0x2a, 0x0a, 0x09, 0x09, 0x09, 0x09, + 0x20, 0x2a, 0x20, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x20, 0x66, + 0x6f, 0x72, 0x20, 0x74, 0x77, 0x6f, 0x2d, 0x63, 0x68, 0x61, 0x6e, 0x6e, + 0x65, 0x6c, 0x20, 0x61, 0x73, 0x79, 0x6e, 0x63, 0x68, 0x72, 0x6f, 0x6e, + 0x6f, 0x75, 0x73, 0x20, 0x68, 0x74, 0x74, 0x70, 0x20, 0x63, 0x6f, 0x6d, + 0x6d, 0x75, 0x6e, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x0a, 0x09, + 0x09, 0x09, 0x09, 0x20, 0x2a, 0x2f, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x66, + 0x6f, 0x72, 0x20, 0x28, 0x76, 0x61, 0x72, 0x20, 0x6b, 0x65, 0x79, 0x20, + 0x69, 0x6e, 0x20, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x29, 0x20, + 0x7b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x20, 0x20, 0x69, 0x66, 0x20, 0x28, + 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x68, 0x61, 0x73, 0x4f, + 0x77, 0x6e, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x28, 0x6b, + 0x65, 0x79, 0x29, 0x29, 0x20, 0x7b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x20, + 0x20, 0x20, 0x20, 0x74, 0x68, 0x69, 0x73, 0x5b, 0x6b, 0x65, 0x79, 0x5d, + 0x20, 0x3d, 0x20, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x5b, 0x6b, + 0x65, 0x79, 0x5d, 0x3b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x20, 0x20, 0x7d, + 0x0a, 0x09, 0x09, 0x09, 0x09, 0x7d, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x76, + 0x61, 0x72, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x20, 0x3d, 0x20, 0x74, 0x68, + 0x69, 0x73, 0x3b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x0a, 0x09, 0x09, 0x09, + 0x09, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x78, 0x68, 0x72, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x3d, 0x20, 0x28, 0x77, 0x69, 0x6e, 0x64, 0x6f, + 0x77, 0x2e, 0x58, 0x4d, 0x4c, 0x48, 0x74, 0x74, 0x70, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x20, 0x3f, 0x20, 0x6e, 0x65, 0x77, 0x20, 0x58, + 0x4d, 0x4c, 0x48, 0x74, 0x74, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x28, 0x29, 0x20, 0x3a, 0x20, 0x6e, 0x65, 0x77, 0x20, 0x41, 0x63, + 0x74, 0x69, 0x76, 0x65, 0x58, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x28, + 0x22, 0x4d, 0x53, 0x58, 0x4d, 0x4c, 0x32, 0x2e, 0x58, 0x4d, 0x4c, 0x48, + 0x54, 0x54, 0x50, 0x2e, 0x33, 0x2e, 0x30, 0x22, 0x29, 0x29, 0x3b, 0x0a, + 0x09, 0x09, 0x09, 0x09, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x63, 0x6f, 0x6d, + 0x65, 0x74, 0x50, 0x6f, 0x6c, 0x6c, 0x20, 0x3d, 0x20, 0x28, 0x77, 0x69, + 0x6e, 0x64, 0x6f, 0x77, 0x2e, 0x58, 0x4d, 0x4c, 0x48, 0x74, 0x74, 0x70, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x20, 0x3f, 0x20, 0x6e, 0x65, + 0x77, 0x20, 0x58, 0x4d, 0x4c, 0x48, 0x74, 0x74, 0x70, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x28, 0x29, 0x20, 0x3a, 0x20, 0x6e, 0x65, 0x77, + 0x20, 0x41, 0x63, 0x74, 0x69, 0x76, 0x65, 0x58, 0x4f, 0x62, 0x6a, 0x65, + 0x63, 0x74, 0x28, 0x22, 0x4d, 0x53, 0x58, 0x4d, 0x4c, 0x32, 0x2e, 0x58, + 0x4d, 0x4c, 0x48, 0x54, 0x54, 0x50, 0x2e, 0x33, 0x2e, 0x30, 0x22, 0x29, + 0x29, 0x3b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x0a, 0x09, 0x09, 0x09, 0x09, + 0x74, 0x68, 0x69, 0x73, 0x2e, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x55, + 0x55, 0x49, 0x44, 0x20, 0x3d, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x28, 0x29, 0x20, 0x7b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, + 0x2f, 0x2f, 0x20, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, + 0x77, 0x2e, 0x69, 0x65, 0x74, 0x66, 0x2e, 0x6f, 0x72, 0x67, 0x2f, 0x72, + 0x66, 0x63, 0x2f, 0x72, 0x66, 0x63, 0x34, 0x31, 0x32, 0x32, 0x2e, 0x74, + 0x78, 0x74, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x76, 0x61, 0x72, 0x20, + 0x73, 0x20, 0x3d, 0x20, 0x5b, 0x5d, 0x3b, 0x0a, 0x09, 0x09, 0x09, 0x09, + 0x09, 0x76, 0x61, 0x72, 0x20, 0x68, 0x65, 0x78, 0x44, 0x69, 0x67, 0x69, + 0x74, 0x73, 0x20, 0x3d, 0x20, 0x22, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, + 0x36, 0x37, 0x38, 0x39, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x22, 0x3b, + 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x66, 0x6f, 0x72, 0x20, 0x28, 0x76, + 0x61, 0x72, 0x20, 0x69, 0x20, 0x3d, 0x20, 0x30, 0x3b, 0x20, 0x69, 0x20, + 0x3c, 0x20, 0x33, 0x36, 0x3b, 0x20, 0x69, 0x2b, 0x2b, 0x29, 0x20, 0x7b, + 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x73, 0x5b, 0x69, 0x5d, 0x20, + 0x3d, 0x20, 0x68, 0x65, 0x78, 0x44, 0x69, 0x67, 0x69, 0x74, 0x73, 0x2e, + 0x73, 0x75, 0x62, 0x73, 0x74, 0x72, 0x28, 0x4d, 0x61, 0x74, 0x68, 0x2e, + 0x66, 0x6c, 0x6f, 0x6f, 0x72, 0x28, 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x72, + 0x61, 0x6e, 0x64, 0x6f, 0x6d, 0x28, 0x29, 0x20, 0x2a, 0x20, 0x30, 0x78, + 0x31, 0x30, 0x29, 0x2c, 0x20, 0x31, 0x29, 0x3b, 0x0a, 0x09, 0x09, 0x09, + 0x09, 0x09, 0x7d, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x73, 0x5b, 0x31, + 0x34, 0x5d, 0x20, 0x3d, 0x20, 0x22, 0x34, 0x22, 0x3b, 0x20, 0x20, 0x2f, + 0x2f, 0x20, 0x62, 0x69, 0x74, 0x73, 0x20, 0x31, 0x32, 0x2d, 0x31, 0x35, + 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x74, 0x69, 0x6d, 0x65, + 0x5f, 0x68, 0x69, 0x5f, 0x61, 0x6e, 0x64, 0x5f, 0x76, 0x65, 0x72, 0x73, + 0x69, 0x6f, 0x6e, 0x20, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x20, 0x74, 0x6f, + 0x20, 0x30, 0x30, 0x31, 0x30, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x73, + 0x5b, 0x31, 0x39, 0x5d, 0x20, 0x3d, 0x20, 0x68, 0x65, 0x78, 0x44, 0x69, + 0x67, 0x69, 0x74, 0x73, 0x2e, 0x73, 0x75, 0x62, 0x73, 0x74, 0x72, 0x28, + 0x28, 0x73, 0x5b, 0x31, 0x39, 0x5d, 0x20, 0x26, 0x20, 0x30, 0x78, 0x33, + 0x29, 0x20, 0x7c, 0x20, 0x30, 0x78, 0x38, 0x2c, 0x20, 0x31, 0x29, 0x3b, + 0x20, 0x20, 0x2f, 0x2f, 0x20, 0x62, 0x69, 0x74, 0x73, 0x20, 0x36, 0x2d, + 0x37, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x6c, 0x6f, + 0x63, 0x6b, 0x5f, 0x73, 0x65, 0x71, 0x5f, 0x68, 0x69, 0x5f, 0x61, 0x6e, + 0x64, 0x5f, 0x72, 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, 0x64, 0x20, 0x74, + 0x6f, 0x20, 0x30, 0x31, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x73, 0x5b, + 0x38, 0x5d, 0x20, 0x3d, 0x20, 0x73, 0x5b, 0x31, 0x33, 0x5d, 0x20, 0x3d, + 0x20, 0x73, 0x5b, 0x31, 0x38, 0x5d, 0x20, 0x3d, 0x20, 0x73, 0x5b, 0x32, + 0x33, 0x5d, 0x20, 0x3d, 0x20, 0x22, 0x2d, 0x22, 0x3b, 0x0a, 0x09, 0x09, + 0x09, 0x09, 0x09, 0x76, 0x61, 0x72, 0x20, 0x75, 0x75, 0x69, 0x64, 0x20, + 0x3d, 0x20, 0x73, 0x2e, 0x6a, 0x6f, 0x69, 0x6e, 0x28, 0x22, 0x22, 0x29, + 0x3b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, + 0x6e, 0x20, 0x75, 0x75, 0x69, 0x64, 0x3b, 0x0a, 0x09, 0x09, 0x09, 0x09, + 0x7d, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x74, + 0x68, 0x69, 0x73, 0x2e, 0x6c, 0x6f, 0x6e, 0x67, 0x70, 0x6f, 0x6c, 0x6c, + 0x20, 0x3d, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, + 0x29, 0x20, 0x7b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x73, 0x65, 0x6c, + 0x66, 0x2e, 0x63, 0x6f, 0x6d, 0x65, 0x74, 0x50, 0x6f, 0x6c, 0x6c, 0x2e, + 0x6f, 0x6e, 0x72, 0x65, 0x61, 0x64, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, + 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x20, 0x3d, 0x20, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x29, 0x20, 0x7b, 0x0a, 0x09, 0x09, + 0x09, 0x09, 0x09, 0x09, 0x69, 0x66, 0x20, 0x28, 0x73, 0x65, 0x6c, 0x66, + 0x2e, 0x63, 0x6f, 0x6d, 0x65, 0x74, 0x50, 0x6f, 0x6c, 0x6c, 0x2e, 0x72, + 0x65, 0x61, 0x64, 0x79, 0x53, 0x74, 0x61, 0x74, 0x65, 0x20, 0x3d, 0x3d, + 0x3d, 0x20, 0x34, 0x29, 0x20, 0x7b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, + 0x09, 0x09, 0x69, 0x66, 0x20, 0x28, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x63, + 0x6f, 0x6d, 0x65, 0x74, 0x50, 0x6f, 0x6c, 0x6c, 0x2e, 0x73, 0x74, 0x61, + 0x74, 0x75, 0x73, 0x20, 0x21, 0x3d, 0x3d, 0x20, 0x32, 0x30, 0x30, 0x29, + 0x20, 0x7b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x73, + 0x65, 0x6c, 0x66, 0x2e, 0x6c, 0x6f, 0x6e, 0x67, 0x70, 0x6f, 0x6c, 0x6c, + 0x28, 0x29, 0x3b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, + 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x3b, 0x0a, 0x09, 0x09, 0x09, 0x09, + 0x09, 0x09, 0x09, 0x7d, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, + 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6f, 0x6e, 0x52, 0x63, 0x76, 0x64, 0x28, + 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x63, 0x6f, 0x6d, 0x65, 0x74, 0x50, 0x6f, + 0x6c, 0x6c, 0x29, 0x3b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, + 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6c, 0x6f, 0x6e, 0x67, 0x70, 0x6f, 0x6c, + 0x6c, 0x28, 0x29, 0x3b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x7d, + 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x7d, 0x3b, 0x0a, 0x09, 0x09, 0x09, + 0x09, 0x09, 0x2f, 0x2f, 0x20, 0x75, 0x73, 0x65, 0x20, 0x74, 0x6f, 0x6b, + 0x65, 0x6e, 0x20, 0x75, 0x6e, 0x74, 0x69, 0x6c, 0x20, 0x77, 0x65, 0x20, + 0x68, 0x61, 0x76, 0x65, 0x20, 0x61, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x65, + 0x78, 0x74, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x73, 0x65, 0x6c, 0x66, + 0x2e, 0x63, 0x6f, 0x6d, 0x65, 0x74, 0x50, 0x6f, 0x6c, 0x6c, 0x2e, 0x6f, + 0x70, 0x65, 0x6e, 0x28, 0x22, 0x47, 0x45, 0x54, 0x22, 0x2c, 0x20, 0x73, + 0x65, 0x6c, 0x66, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x2b, + 0x20, 0x28, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, + 0x20, 0x3f, 0x20, 0x22, 0x3f, 0x22, 0x20, 0x2b, 0x20, 0x73, 0x65, 0x6c, + 0x66, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x20, 0x3a, 0x20, 0x22, 0x22, + 0x29, 0x29, 0x3b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x73, 0x65, 0x6c, + 0x66, 0x2e, 0x63, 0x6f, 0x6d, 0x65, 0x74, 0x50, 0x6f, 0x6c, 0x6c, 0x2e, + 0x73, 0x65, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x48, 0x65, + 0x61, 0x64, 0x65, 0x72, 0x28, 0x27, 0x58, 0x2d, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x65, 0x64, 0x2d, 0x57, 0x69, 0x74, 0x68, 0x27, 0x2c, + 0x20, 0x27, 0x58, 0x4d, 0x4c, 0x48, 0x74, 0x74, 0x70, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x27, 0x29, 0x3b, 0x0a, 0x09, 0x09, 0x09, 0x09, + 0x09, 0x2f, 0x2f, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x63, 0x6f, 0x6d, + 0x65, 0x74, 0x50, 0x6f, 0x6c, 0x6c, 0x2e, 0x73, 0x65, 0x74, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x28, + 0x22, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x22, + 0x2c, 0x20, 0x22, 0x63, 0x6c, 0x6f, 0x73, 0x65, 0x22, 0x29, 0x3b, 0x0a, + 0x09, 0x09, 0x09, 0x09, 0x09, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x63, 0x6f, + 0x6d, 0x65, 0x74, 0x50, 0x6f, 0x6c, 0x6c, 0x2e, 0x73, 0x65, 0x6e, 0x64, + 0x28, 0x6e, 0x75, 0x6c, 0x6c, 0x29, 0x3b, 0x0a, 0x09, 0x09, 0x09, 0x09, + 0x7d, 0x3b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x0a, 0x09, 0x09, 0x09, 0x09, + 0x74, 0x68, 0x69, 0x73, 0x2e, 0x64, 0x69, 0x73, 0x63, 0x6f, 0x6e, 0x6e, + 0x65, 0x63, 0x74, 0x20, 0x3d, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x28, 0x29, 0x20, 0x7b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, + 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x78, 0x68, 0x72, 0x2e, 0x6f, 0x70, 0x65, + 0x6e, 0x28, 0x22, 0x50, 0x4f, 0x53, 0x54, 0x22, 0x2c, 0x20, 0x73, 0x65, + 0x6c, 0x66, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x2b, 0x20, + 0x28, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x20, + 0x3f, 0x20, 0x22, 0x3f, 0x22, 0x20, 0x2b, 0x20, 0x73, 0x65, 0x6c, 0x66, + 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x20, 0x3a, 0x20, 0x22, 0x22, 0x29, + 0x2c, 0x20, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x29, 0x3b, 0x0a, 0x09, 0x09, + 0x09, 0x09, 0x09, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x78, 0x68, 0x72, 0x2e, + 0x73, 0x65, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x48, 0x65, + 0x61, 0x64, 0x65, 0x72, 0x28, 0x27, 0x58, 0x2d, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x65, 0x64, 0x2d, 0x57, 0x69, 0x74, 0x68, 0x27, 0x2c, + 0x20, 0x27, 0x58, 0x4d, 0x4c, 0x48, 0x74, 0x74, 0x70, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x27, 0x29, 0x3b, 0x0a, 0x09, 0x09, 0x09, 0x09, + 0x09, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x78, 0x68, 0x72, 0x2e, 0x73, 0x65, + 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x48, 0x65, 0x61, 0x64, + 0x65, 0x72, 0x28, 0x27, 0x58, 0x2d, 0x53, 0x43, 0x58, 0x4d, 0x4c, 0x2d, + 0x4e, 0x61, 0x6d, 0x65, 0x27, 0x2c, 0x20, 0x22, 0x64, 0x6f, 0x6e, 0x65, + 0x2e, 0x69, 0x6e, 0x76, 0x6f, 0x6b, 0x65, 0x22, 0x29, 0x3b, 0x0a, 0x09, + 0x09, 0x09, 0x09, 0x09, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x78, 0x68, 0x72, + 0x2e, 0x73, 0x65, 0x6e, 0x64, 0x28, 0x4e, 0x55, 0x4c, 0x4c, 0x29, 0x3b, + 0x0a, 0x09, 0x09, 0x09, 0x09, 0x7d, 0x3b, 0x0a, 0x09, 0x09, 0x09, 0x09, + 0x0a, 0x09, 0x09, 0x09, 0x09, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x70, 0x6f, + 0x73, 0x74, 0x20, 0x3d, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x28, 0x6e, 0x61, 0x6d, 0x65, 0x2c, 0x20, 0x64, 0x61, 0x74, 0x61, + 0x2c, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, + 0x65, 0x29, 0x20, 0x7b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x73, 0x65, + 0x6c, 0x66, 0x2e, 0x78, 0x68, 0x72, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x28, + 0x22, 0x50, 0x4f, 0x53, 0x54, 0x22, 0x2c, 0x20, 0x73, 0x65, 0x6c, 0x66, + 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x2b, 0x20, 0x28, 0x73, + 0x65, 0x6c, 0x66, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x20, 0x3f, 0x20, + 0x22, 0x3f, 0x22, 0x20, 0x2b, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x71, + 0x75, 0x65, 0x72, 0x79, 0x20, 0x3a, 0x20, 0x22, 0x22, 0x29, 0x29, 0x3b, + 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x78, + 0x68, 0x72, 0x2e, 0x73, 0x65, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x28, 0x27, 0x58, 0x2d, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x65, 0x64, 0x2d, 0x57, 0x69, 0x74, + 0x68, 0x27, 0x2c, 0x20, 0x27, 0x58, 0x4d, 0x4c, 0x48, 0x74, 0x74, 0x70, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x27, 0x29, 0x3b, 0x0a, 0x09, + 0x09, 0x09, 0x09, 0x09, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x78, 0x68, 0x72, + 0x2e, 0x73, 0x65, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x48, + 0x65, 0x61, 0x64, 0x65, 0x72, 0x28, 0x27, 0x58, 0x2d, 0x53, 0x43, 0x58, + 0x4d, 0x4c, 0x2d, 0x4e, 0x61, 0x6d, 0x65, 0x27, 0x2c, 0x20, 0x6e, 0x61, + 0x6d, 0x65, 0x29, 0x3b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x69, 0x66, + 0x20, 0x28, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, + 0x65, 0x29, 0x20, 0x7b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x73, + 0x65, 0x6c, 0x66, 0x2e, 0x78, 0x68, 0x72, 0x2e, 0x73, 0x65, 0x74, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, + 0x28, 0x27, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x54, 0x79, + 0x70, 0x65, 0x27, 0x2c, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, + 0x54, 0x79, 0x70, 0x65, 0x29, 0x3b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, + 0x7d, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x73, 0x65, 0x6c, 0x66, 0x2e, + 0x78, 0x68, 0x72, 0x2e, 0x73, 0x65, 0x6e, 0x64, 0x28, 0x64, 0x61, 0x74, + 0x61, 0x29, 0x3b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x7d, 0x0a, 0x09, 0x09, + 0x09, 0x09, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x2f, 0x2f, 0x20, 0x73, 0x65, + 0x72, 0x69, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x20, 0x61, 0x6e, 0x20, 0x6f, + 0x62, 0x6a, 0x65, 0x63, 0x74, 0x20, 0x74, 0x6f, 0x20, 0x62, 0x65, 0x20, + 0x73, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x74, 0x68, 0x69, + 0x73, 0x2e, 0x73, 0x65, 0x6e, 0x64, 0x20, 0x3d, 0x20, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x61, 0x6d, 0x65, 0x2c, 0x20, + 0x74, 0x68, 0x69, 0x6e, 0x67, 0x29, 0x20, 0x7b, 0x0a, 0x09, 0x09, 0x09, + 0x09, 0x09, 0x76, 0x61, 0x72, 0x20, 0x64, 0x61, 0x74, 0x61, 0x3b, 0x0a, + 0x09, 0x09, 0x09, 0x09, 0x09, 0x2f, 0x2f, 0x20, 0x73, 0x65, 0x65, 0x20, + 0x61, 0x6c, 0x73, 0x6f, 0x3a, 0x20, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, + 0x2f, 0x2f, 0x72, 0x61, 0x77, 0x2e, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, + 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x64, 0x6f, 0x75, 0x67, 0x6c, 0x61, 0x73, + 0x63, 0x72, 0x6f, 0x63, 0x6b, 0x66, 0x6f, 0x72, 0x64, 0x2f, 0x4a, 0x53, + 0x4f, 0x4e, 0x2d, 0x6a, 0x73, 0x2f, 0x6d, 0x61, 0x73, 0x74, 0x65, 0x72, + 0x2f, 0x63, 0x79, 0x63, 0x6c, 0x65, 0x2e, 0x6a, 0x73, 0x0a, 0x09, 0x09, + 0x09, 0x09, 0x09, 0x2f, 0x2f, 0x20, 0x64, 0x69, 0x73, 0x70, 0x61, 0x74, + 0x63, 0x68, 0x20, 0x6f, 0x76, 0x65, 0x72, 0x20, 0x74, 0x68, 0x69, 0x6e, + 0x67, 0x79, 0x20, 0x74, 0x79, 0x70, 0x65, 0x20, 0x68, 0x65, 0x72, 0x65, + 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x69, 0x66, 0x20, 0x28, 0x74, 0x79, + 0x70, 0x65, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x69, 0x6e, 0x67, 0x20, 0x3d, + 0x3d, 0x3d, 0x20, 0x22, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x22, 0x29, + 0x20, 0x7b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x76, 0x61, 0x72, + 0x20, 0x73, 0x65, 0x65, 0x6e, 0x20, 0x3d, 0x20, 0x5b, 0x5d, 0x3b, 0x0a, + 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x2f, 0x2f, 0x20, 0x77, 0x69, 0x6c, + 0x6c, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x77, 0x6f, 0x72, 0x6b, 0x20, 0x6f, + 0x6e, 0x20, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x20, 0x61, 0x73, 0x20, 0x74, + 0x68, 0x69, 0x6e, 0x67, 0x20, 0x69, 0x73, 0x20, 0x63, 0x68, 0x65, 0x63, + 0x6b, 0x65, 0x64, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x63, 0x79, 0x63, 0x6c, + 0x65, 0x73, 0x20, 0x66, 0x69, 0x72, 0x73, 0x74, 0x0a, 0x09, 0x09, 0x09, + 0x09, 0x09, 0x09, 0x64, 0x61, 0x74, 0x61, 0x20, 0x3d, 0x20, 0x4a, 0x53, + 0x4f, 0x4e, 0x2e, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x69, 0x66, 0x79, + 0x28, 0x74, 0x68, 0x69, 0x6e, 0x67, 0x2c, 0x20, 0x66, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6b, 0x65, 0x79, 0x2c, 0x20, 0x76, 0x61, + 0x6c, 0x29, 0x20, 0x7b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, + 0x69, 0x66, 0x20, 0x28, 0x69, 0x73, 0x4e, 0x6f, 0x64, 0x65, 0x28, 0x76, + 0x61, 0x6c, 0x29, 0x29, 0x20, 0x7b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, + 0x09, 0x09, 0x09, 0x2f, 0x2f, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, + 0x20, 0x61, 0x20, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x20, 0x6f, 0x66, 0x20, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, + 0x65, 0x73, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x72, + 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x7b, 0x0a, 0x09, 0x09, 0x09, 0x09, + 0x09, 0x09, 0x09, 0x09, 0x09, 0x69, 0x64, 0x3a, 0x20, 0x76, 0x61, 0x6c, + 0x2e, 0x69, 0x64, 0x2c, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, + 0x09, 0x09, 0x74, 0x61, 0x67, 0x4e, 0x61, 0x6d, 0x65, 0x3a, 0x20, 0x76, + 0x61, 0x6c, 0x2e, 0x74, 0x61, 0x67, 0x4e, 0x61, 0x6d, 0x65, 0x2c, 0x0a, + 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x6c, 0x6f, 0x63, + 0x61, 0x6c, 0x4e, 0x61, 0x6d, 0x65, 0x3a, 0x20, 0x76, 0x61, 0x6c, 0x2e, + 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x4e, 0x61, 0x6d, 0x65, 0x0a, 0x09, 0x09, + 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x7d, 0x3b, 0x0a, 0x09, 0x09, 0x09, + 0x09, 0x09, 0x09, 0x09, 0x7d, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, + 0x09, 0x69, 0x66, 0x20, 0x28, 0x69, 0x73, 0x57, 0x69, 0x6e, 0x64, 0x6f, + 0x77, 0x28, 0x76, 0x61, 0x6c, 0x29, 0x29, 0x20, 0x7b, 0x0a, 0x09, 0x09, + 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, + 0x3b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x7d, 0x0a, 0x09, + 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x69, 0x66, 0x20, 0x28, 0x74, 0x79, + 0x70, 0x65, 0x6f, 0x66, 0x20, 0x76, 0x61, 0x6c, 0x20, 0x3d, 0x3d, 0x3d, + 0x20, 0x22, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x22, 0x29, 0x20, 0x7b, + 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x69, 0x66, 0x20, + 0x28, 0x73, 0x65, 0x65, 0x6e, 0x2e, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x4f, + 0x66, 0x28, 0x76, 0x61, 0x6c, 0x29, 0x20, 0x3e, 0x3d, 0x20, 0x30, 0x29, + 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x72, 0x65, + 0x74, 0x75, 0x72, 0x6e, 0x3b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, + 0x09, 0x09, 0x73, 0x65, 0x65, 0x6e, 0x2e, 0x70, 0x75, 0x73, 0x68, 0x28, + 0x76, 0x61, 0x6c, 0x29, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, + 0x7d, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x72, 0x65, 0x74, + 0x75, 0x72, 0x6e, 0x20, 0x76, 0x61, 0x6c, 0x0a, 0x09, 0x09, 0x09, 0x09, + 0x09, 0x09, 0x7d, 0x29, 0x3b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x7d, + 0x20, 0x65, 0x6c, 0x73, 0x65, 0x20, 0x7b, 0x0a, 0x09, 0x09, 0x09, 0x09, + 0x09, 0x09, 0x64, 0x61, 0x74, 0x61, 0x20, 0x3d, 0x20, 0x74, 0x68, 0x69, + 0x6e, 0x67, 0x3b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x7d, 0x0a, 0x09, + 0x09, 0x09, 0x09, 0x09, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x70, 0x6f, 0x73, + 0x74, 0x28, 0x6e, 0x61, 0x6d, 0x65, 0x2c, 0x20, 0x64, 0x61, 0x74, 0x61, + 0x2c, 0x20, 0x22, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x2f, 0x6a, 0x73, 0x6f, 0x6e, 0x22, 0x29, 0x3b, 0x0a, 0x09, + 0x09, 0x09, 0x09, 0x7d, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x0a, 0x09, 0x09, + 0x09, 0x09, 0x2f, 0x2f, 0x20, 0x68, 0x65, 0x6c, 0x70, 0x65, 0x72, 0x20, + 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x74, 0x6f, 0x20, + 0x64, 0x65, 0x74, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x65, 0x20, 0x77, 0x68, + 0x65, 0x74, 0x68, 0x65, 0x72, 0x20, 0x73, 0x6f, 0x6d, 0x65, 0x74, 0x68, + 0x69, 0x6e, 0x67, 0x20, 0x69, 0x73, 0x20, 0x61, 0x20, 0x68, 0x74, 0x6d, + 0x6c, 0x20, 0x6e, 0x6f, 0x64, 0x65, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x76, + 0x61, 0x72, 0x20, 0x69, 0x73, 0x4e, 0x6f, 0x64, 0x65, 0x20, 0x3d, 0x20, + 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6f, 0x29, 0x7b, + 0x0a, 0x09, 0x09, 0x09, 0x09, 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, + 0x6e, 0x20, 0x28, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x20, 0x20, 0x20, 0x20, + 0x74, 0x79, 0x70, 0x65, 0x6f, 0x66, 0x20, 0x4e, 0x6f, 0x64, 0x65, 0x20, + 0x3d, 0x3d, 0x3d, 0x20, 0x22, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x22, + 0x20, 0x3f, 0x20, 0x6f, 0x20, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, + 0x65, 0x6f, 0x66, 0x20, 0x4e, 0x6f, 0x64, 0x65, 0x20, 0x3a, 0x20, 0x0a, + 0x09, 0x09, 0x09, 0x09, 0x20, 0x20, 0x20, 0x20, 0x6f, 0x20, 0x26, 0x26, + 0x20, 0x74, 0x79, 0x70, 0x65, 0x6f, 0x66, 0x20, 0x6f, 0x20, 0x3d, 0x3d, + 0x3d, 0x20, 0x22, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x22, 0x20, 0x26, + 0x26, 0x20, 0x74, 0x79, 0x70, 0x65, 0x6f, 0x66, 0x20, 0x6f, 0x2e, 0x6e, + 0x6f, 0x64, 0x65, 0x54, 0x79, 0x70, 0x65, 0x20, 0x3d, 0x3d, 0x3d, 0x20, + 0x22, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x22, 0x20, 0x26, 0x26, 0x20, + 0x74, 0x79, 0x70, 0x65, 0x6f, 0x66, 0x20, 0x6f, 0x2e, 0x6e, 0x6f, 0x64, + 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x3d, 0x3d, 0x3d, 0x22, 0x73, 0x74, 0x72, + 0x69, 0x6e, 0x67, 0x22, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x20, 0x20, 0x29, + 0x3b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x7d, 0x0a, 0x0a, 0x09, 0x09, 0x09, + 0x09, 0x2f, 0x2f, 0x20, 0x68, 0x65, 0x6c, 0x70, 0x65, 0x72, 0x20, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x74, 0x6f, 0x20, 0x64, + 0x65, 0x74, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x65, 0x20, 0x77, 0x68, 0x65, + 0x74, 0x68, 0x65, 0x72, 0x20, 0x73, 0x6f, 0x6d, 0x65, 0x74, 0x68, 0x69, + 0x6e, 0x67, 0x20, 0x69, 0x73, 0x20, 0x61, 0x20, 0x77, 0x69, 0x6e, 0x64, + 0x6f, 0x77, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x76, 0x61, 0x72, 0x20, 0x69, + 0x73, 0x57, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x20, 0x3d, 0x20, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6f, 0x29, 0x7b, 0x0a, 0x09, + 0x09, 0x09, 0x09, 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, + 0x28, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x20, 0x20, 0x20, 0x20, 0x74, 0x79, + 0x70, 0x65, 0x6f, 0x66, 0x20, 0x57, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x20, + 0x3d, 0x3d, 0x3d, 0x20, 0x22, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x22, + 0x20, 0x3f, 0x20, 0x6f, 0x20, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, + 0x65, 0x6f, 0x66, 0x20, 0x57, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x20, 0x3a, + 0x20, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x20, 0x20, 0x20, 0x20, 0x6f, 0x20, + 0x26, 0x26, 0x20, 0x74, 0x79, 0x70, 0x65, 0x6f, 0x66, 0x20, 0x6f, 0x20, + 0x3d, 0x3d, 0x3d, 0x20, 0x22, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x22, + 0x20, 0x26, 0x26, 0x20, 0x74, 0x79, 0x70, 0x65, 0x6f, 0x66, 0x20, 0x6f, + 0x2e, 0x6d, 0x65, 0x6e, 0x75, 0x62, 0x61, 0x72, 0x20, 0x3d, 0x3d, 0x3d, + 0x20, 0x22, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x22, 0x0a, 0x09, 0x09, + 0x09, 0x09, 0x20, 0x20, 0x29, 0x3b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x7d, + 0x0a, 0x09, 0x09, 0x09, 0x09, 0x0a, 0x09, 0x09, 0x09, 0x7d, 0x0a, 0x09, + 0x09, 0x0a, 0x09, 0x09, 0x3c, 0x2f, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, + 0x3e, 0x0a, 0x09, 0x09, 0x0a, 0x09, 0x09, 0x3c, 0x73, 0x63, 0x72, 0x69, + 0x70, 0x74, 0x20, 0x74, 0x79, 0x70, 0x65, 0x3d, 0x22, 0x74, 0x65, 0x78, + 0x74, 0x2f, 0x6a, 0x61, 0x76, 0x61, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, + 0x22, 0x3e, 0x0a, 0x09, 0x09, 0x09, 0x64, 0x6f, 0x6d, 0x4c, 0x6f, 0x61, + 0x64, 0x65, 0x64, 0x28, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x20, 0x28, 0x29, 0x20, 0x7b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x73, 0x63, + 0x78, 0x6d, 0x6c, 0x20, 0x3d, 0x20, 0x6e, 0x65, 0x77, 0x20, 0x43, 0x6f, + 0x6d, 0x65, 0x74, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x28, 0x7b, + 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x2f, 0x2f, 0x65, 0x6c, 0x65, 0x6d, + 0x65, 0x6e, 0x74, 0x3a, 0x20, 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, + 0x74, 0x2e, 0x67, 0x65, 0x74, 0x45, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, + 0x42, 0x79, 0x49, 0x64, 0x28, 0x22, 0x24, 0x7b, 0x73, 0x63, 0x78, 0x6d, + 0x6c, 0x2e, 0x69, 0x6e, 0x76, 0x6f, 0x6b, 0x65, 0x49, 0x64, 0x7d, 0x22, + 0x29, 0x2c, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x73, 0x65, 0x72, 0x76, + 0x65, 0x72, 0x3a, 0x20, 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, + 0x2e, 0x55, 0x52, 0x4c, 0x2c, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x6f, + 0x6e, 0x52, 0x63, 0x76, 0x64, 0x20, 0x3a, 0x20, 0x66, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x64, 0x61, 0x74, 0x61, 0x29, 0x20, 0x7b, + 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x69, 0x66, 0x20, 0x28, 0x64, + 0x61, 0x74, 0x61, 0x2e, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x58, 0x4d, 0x4c, 0x29, 0x20, 0x7b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, + 0x09, 0x09, 0x76, 0x61, 0x72, 0x20, 0x74, 0x79, 0x70, 0x65, 0x20, 0x3d, + 0x20, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x67, 0x65, 0x74, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x28, + 0x22, 0x58, 0x2d, 0x53, 0x43, 0x58, 0x4d, 0x4c, 0x2d, 0x54, 0x79, 0x70, + 0x65, 0x22, 0x29, 0x20, 0x7c, 0x7c, 0x20, 0x22, 0x72, 0x65, 0x70, 0x6c, + 0x61, 0x63, 0x65, 0x63, 0x68, 0x69, 0x6c, 0x64, 0x72, 0x65, 0x6e, 0x22, + 0x3b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x76, 0x61, 0x72, + 0x20, 0x64, 0x6f, 0x6d, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x20, 0x3d, + 0x20, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x67, 0x65, 0x74, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x28, + 0x22, 0x58, 0x2d, 0x53, 0x43, 0x58, 0x4d, 0x4c, 0x2d, 0x58, 0x50, 0x61, + 0x74, 0x68, 0x22, 0x29, 0x20, 0x7c, 0x7c, 0x20, 0x22, 0x2f, 0x68, 0x74, + 0x6d, 0x6c, 0x2f, 0x62, 0x6f, 0x64, 0x79, 0x22, 0x3b, 0x0a, 0x09, 0x09, + 0x09, 0x09, 0x09, 0x09, 0x09, 0x76, 0x61, 0x72, 0x20, 0x64, 0x6f, 0x6d, + 0x41, 0x74, 0x74, 0x72, 0x20, 0x3d, 0x20, 0x64, 0x61, 0x74, 0x61, 0x2e, + 0x67, 0x65, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x48, + 0x65, 0x61, 0x64, 0x65, 0x72, 0x28, 0x22, 0x58, 0x2d, 0x53, 0x43, 0x58, + 0x4d, 0x4c, 0x2d, 0x41, 0x74, 0x74, 0x72, 0x22, 0x29, 0x3b, 0x0a, 0x09, + 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x76, 0x61, 0x72, 0x20, 0x72, 0x65, + 0x73, 0x75, 0x6c, 0x74, 0x20, 0x3d, 0x20, 0x64, 0x6f, 0x63, 0x75, 0x6d, + 0x65, 0x6e, 0x74, 0x2e, 0x65, 0x76, 0x61, 0x6c, 0x75, 0x61, 0x74, 0x65, + 0x28, 0x64, 0x6f, 0x6d, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x2c, 0x20, + 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x2c, 0x20, 0x6e, 0x75, + 0x6c, 0x6c, 0x2c, 0x20, 0x58, 0x50, 0x61, 0x74, 0x68, 0x52, 0x65, 0x73, + 0x75, 0x6c, 0x74, 0x2e, 0x4f, 0x52, 0x44, 0x45, 0x52, 0x45, 0x44, 0x5f, + 0x4e, 0x4f, 0x44, 0x45, 0x5f, 0x53, 0x4e, 0x41, 0x50, 0x53, 0x48, 0x4f, + 0x54, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x2c, 0x20, 0x6e, 0x75, 0x6c, 0x6c, + 0x29, 0x3b, 0x0a, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x66, + 0x6f, 0x72, 0x20, 0x28, 0x76, 0x61, 0x72, 0x20, 0x69, 0x20, 0x3d, 0x20, + 0x30, 0x2c, 0x20, 0x6c, 0x20, 0x3d, 0x20, 0x72, 0x65, 0x73, 0x75, 0x6c, + 0x74, 0x2e, 0x73, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x4c, 0x65, + 0x6e, 0x67, 0x74, 0x68, 0x3b, 0x20, 0x69, 0x20, 0x3c, 0x20, 0x6c, 0x3b, + 0x20, 0x69, 0x2b, 0x2b, 0x29, 0x20, 0x7b, 0x0a, 0x09, 0x09, 0x09, 0x09, + 0x09, 0x09, 0x09, 0x09, 0x76, 0x61, 0x72, 0x20, 0x69, 0x74, 0x65, 0x6d, + 0x20, 0x3d, 0x20, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x2e, 0x73, 0x6e, + 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x49, 0x74, 0x65, 0x6d, 0x28, 0x69, + 0x29, 0x3b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x76, + 0x61, 0x72, 0x20, 0x6e, 0x6f, 0x64, 0x65, 0x20, 0x3d, 0x20, 0x64, 0x6f, + 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x69, 0x6d, 0x70, 0x6f, 0x72, + 0x74, 0x4e, 0x6f, 0x64, 0x65, 0x28, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x72, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x58, 0x4d, 0x4c, 0x2e, 0x66, + 0x69, 0x72, 0x73, 0x74, 0x43, 0x68, 0x69, 0x6c, 0x64, 0x2c, 0x20, 0x74, + 0x72, 0x75, 0x65, 0x29, 0x3b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, + 0x09, 0x09, 0x73, 0x77, 0x69, 0x74, 0x63, 0x68, 0x20, 0x28, 0x74, 0x79, + 0x70, 0x65, 0x29, 0x20, 0x7b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, + 0x09, 0x09, 0x09, 0x63, 0x61, 0x73, 0x65, 0x20, 0x22, 0x66, 0x69, 0x72, + 0x73, 0x74, 0x63, 0x68, 0x69, 0x6c, 0x64, 0x22, 0x3a, 0x0a, 0x09, 0x09, + 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x69, 0x74, 0x65, 0x6d, + 0x2e, 0x69, 0x6e, 0x73, 0x65, 0x72, 0x74, 0x42, 0x65, 0x66, 0x6f, 0x72, + 0x65, 0x28, 0x6e, 0x6f, 0x64, 0x65, 0x2c, 0x20, 0x69, 0x74, 0x65, 0x6d, + 0x2e, 0x66, 0x69, 0x72, 0x73, 0x74, 0x43, 0x68, 0x69, 0x6c, 0x64, 0x29, + 0x3b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x62, + 0x72, 0x65, 0x61, 0x6b, 0x3b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, + 0x09, 0x09, 0x09, 0x63, 0x61, 0x73, 0x65, 0x20, 0x22, 0x6c, 0x61, 0x73, + 0x74, 0x63, 0x68, 0x69, 0x6c, 0x64, 0x22, 0x3a, 0x0a, 0x09, 0x09, 0x09, + 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x69, 0x74, 0x65, 0x6d, 0x2e, + 0x61, 0x70, 0x70, 0x65, 0x6e, 0x64, 0x43, 0x68, 0x69, 0x6c, 0x64, 0x28, + 0x6e, 0x6f, 0x64, 0x65, 0x29, 0x3b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, + 0x09, 0x09, 0x09, 0x09, 0x62, 0x72, 0x65, 0x61, 0x6b, 0x3b, 0x0a, 0x09, + 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x63, 0x61, 0x73, 0x65, + 0x20, 0x22, 0x70, 0x72, 0x65, 0x76, 0x69, 0x6f, 0x75, 0x73, 0x73, 0x69, + 0x62, 0x6c, 0x69, 0x6e, 0x67, 0x22, 0x3a, 0x0a, 0x09, 0x09, 0x09, 0x09, + 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x69, 0x74, 0x65, 0x6d, 0x2e, 0x70, + 0x61, 0x72, 0x65, 0x6e, 0x74, 0x4e, 0x6f, 0x64, 0x65, 0x2e, 0x69, 0x6e, + 0x73, 0x65, 0x72, 0x74, 0x42, 0x65, 0x66, 0x6f, 0x72, 0x65, 0x28, 0x6e, + 0x6f, 0x64, 0x65, 0x2c, 0x20, 0x69, 0x74, 0x65, 0x6d, 0x29, 0x3b, 0x0a, + 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x62, 0x72, 0x65, + 0x61, 0x6b, 0x3b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, + 0x09, 0x63, 0x61, 0x73, 0x65, 0x20, 0x22, 0x6e, 0x65, 0x78, 0x74, 0x73, + 0x69, 0x62, 0x6c, 0x69, 0x6e, 0x67, 0x22, 0x3a, 0x0a, 0x09, 0x09, 0x09, + 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x69, 0x74, 0x65, 0x6d, 0x2e, + 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x4e, 0x6f, 0x64, 0x65, 0x2e, 0x69, + 0x6e, 0x73, 0x65, 0x72, 0x74, 0x42, 0x65, 0x66, 0x6f, 0x72, 0x65, 0x28, + 0x6e, 0x6f, 0x64, 0x65, 0x2c, 0x20, 0x69, 0x74, 0x65, 0x6d, 0x2e, 0x6e, + 0x65, 0x78, 0x74, 0x53, 0x69, 0x62, 0x6c, 0x69, 0x6e, 0x67, 0x29, 0x3b, + 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x62, 0x72, + 0x65, 0x61, 0x6b, 0x3b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, + 0x09, 0x09, 0x63, 0x61, 0x73, 0x65, 0x20, 0x22, 0x72, 0x65, 0x70, 0x6c, + 0x61, 0x63, 0x65, 0x22, 0x3a, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, + 0x09, 0x09, 0x09, 0x09, 0x69, 0x74, 0x65, 0x6d, 0x2e, 0x70, 0x61, 0x72, + 0x65, 0x6e, 0x74, 0x4e, 0x6f, 0x64, 0x65, 0x2e, 0x72, 0x65, 0x70, 0x6c, + 0x61, 0x63, 0x65, 0x43, 0x68, 0x69, 0x6c, 0x64, 0x28, 0x6e, 0x6f, 0x64, + 0x65, 0x2c, 0x20, 0x69, 0x74, 0x65, 0x6d, 0x29, 0x3b, 0x0a, 0x09, 0x09, + 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x62, 0x72, 0x65, 0x61, 0x6b, + 0x3b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x63, + 0x61, 0x73, 0x65, 0x20, 0x22, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x22, + 0x3a, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, + 0x69, 0x74, 0x65, 0x6d, 0x2e, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x4e, + 0x6f, 0x64, 0x65, 0x2e, 0x72, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x43, 0x68, + 0x69, 0x6c, 0x64, 0x28, 0x69, 0x74, 0x65, 0x6d, 0x29, 0x3b, 0x0a, 0x09, + 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x62, 0x72, 0x65, 0x61, + 0x6b, 0x3b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, + 0x63, 0x61, 0x73, 0x65, 0x20, 0x22, 0x61, 0x64, 0x64, 0x61, 0x74, 0x74, + 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x22, 0x3a, 0x0a, 0x09, 0x09, 0x09, + 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x69, 0x74, 0x65, 0x6d, 0x2e, + 0x73, 0x65, 0x74, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, + 0x28, 0x64, 0x6f, 0x6d, 0x41, 0x74, 0x74, 0x72, 0x2c, 0x20, 0x6e, 0x6f, + 0x64, 0x65, 0x29, 0x3b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, + 0x09, 0x09, 0x62, 0x72, 0x65, 0x61, 0x6b, 0x3b, 0x0a, 0x09, 0x09, 0x09, + 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x63, 0x61, 0x73, 0x65, 0x20, 0x22, + 0x72, 0x65, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x63, 0x68, 0x69, 0x6c, 0x64, + 0x72, 0x65, 0x6e, 0x22, 0x3a, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, + 0x09, 0x09, 0x09, 0x09, 0x77, 0x68, 0x69, 0x6c, 0x65, 0x28, 0x69, 0x74, + 0x65, 0x6d, 0x2e, 0x68, 0x61, 0x73, 0x43, 0x68, 0x69, 0x6c, 0x64, 0x4e, + 0x6f, 0x64, 0x65, 0x73, 0x28, 0x29, 0x29, 0x20, 0x7b, 0x0a, 0x09, 0x09, + 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x69, 0x74, 0x65, + 0x6d, 0x2e, 0x72, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x43, 0x68, 0x69, 0x6c, + 0x64, 0x28, 0x69, 0x74, 0x65, 0x6d, 0x2e, 0x66, 0x69, 0x72, 0x73, 0x74, + 0x43, 0x68, 0x69, 0x6c, 0x64, 0x29, 0x3b, 0x0a, 0x09, 0x09, 0x09, 0x09, + 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x7d, 0x0a, 0x09, 0x09, 0x09, 0x09, + 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x69, 0x74, 0x65, 0x6d, 0x2e, 0x61, + 0x70, 0x70, 0x65, 0x6e, 0x64, 0x43, 0x68, 0x69, 0x6c, 0x64, 0x28, 0x6e, + 0x6f, 0x64, 0x65, 0x29, 0x3b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, + 0x09, 0x09, 0x09, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x3a, 0x0a, + 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x62, 0x72, 0x65, + 0x61, 0x6b, 0x3b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, + 0x7d, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x7d, 0x0a, 0x09, + 0x09, 0x09, 0x09, 0x09, 0x09, 0x7d, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, + 0x7d, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x7d, 0x29, 0x3b, 0x0a, 0x09, 0x09, + 0x09, 0x09, 0x73, 0x63, 0x78, 0x6d, 0x6c, 0x2e, 0x6c, 0x6f, 0x6e, 0x67, + 0x70, 0x6f, 0x6c, 0x6c, 0x28, 0x29, 0x3b, 0x0a, 0x09, 0x09, 0x09, 0x09, + 0x5f, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x20, 0x3d, 0x20, 0x73, 0x63, + 0x78, 0x6d, 0x6c, 0x3b, 0x0a, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x77, 0x69, + 0x6e, 0x64, 0x6f, 0x77, 0x2e, 0x6f, 0x6e, 0x62, 0x65, 0x66, 0x6f, 0x72, + 0x65, 0x75, 0x6e, 0x6c, 0x6f, 0x61, 0x64, 0x20, 0x3d, 0x20, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x65, 0x29, 0x20, 0x7b, + 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x73, 0x63, 0x78, 0x6d, 0x6c, 0x2e, + 0x64, 0x69, 0x73, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x28, 0x29, + 0x3b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x2f, 0x2f, 0x20, 0x72, 0x65, + 0x74, 0x75, 0x72, 0x6e, 0x20, 0x27, 0x59, 0x6f, 0x75, 0x20, 0x68, 0x61, + 0x76, 0x65, 0x20, 0x75, 0x6e, 0x73, 0x61, 0x76, 0x65, 0x64, 0x20, 0x63, + 0x68, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x21, 0x27, 0x3b, 0x0a, 0x09, 0x09, + 0x09, 0x09, 0x7d, 0x3b, 0x0a, 0x09, 0x09, 0x09, 0x7d, 0x29, 0x3b, 0x0a, + 0x09, 0x09, 0x3c, 0x2f, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x3e, 0x0a, + 0x0a, 0x09, 0x3c, 0x2f, 0x68, 0x65, 0x61, 0x64, 0x3e, 0x0a, 0x09, 0x3c, + 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x3c, 0x2f, 0x62, 0x6f, 0x64, 0x79, 0x3e, + 0x0a, 0x3c, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x3e, 0x0a }; unsigned int template_xhtml_invoker_html_len = 8253; diff --git a/src/uscxml/plugins/ioprocessor/basichttp/BasicHTTPIOProcessor.cpp b/src/uscxml/plugins/ioprocessor/basichttp/BasicHTTPIOProcessor.cpp index b1fb141..49aa8dc 100644 --- a/src/uscxml/plugins/ioprocessor/basichttp/BasicHTTPIOProcessor.cpp +++ b/src/uscxml/plugins/ioprocessor/basichttp/BasicHTTPIOProcessor.cpp @@ -124,17 +124,18 @@ bool BasicHTTPIOProcessor::httpRecvRequest(const HTTPServer::Request& req) { * raises. */ - { // if we sent ourself an event it will end up here - // this will call the const subscript operator - if (req.data.at("content").hasKey("_scxmleventname")) { - reqEvent.name = req.data.at("content").at("_scxmleventname").atom; - } - if (req.data.at("content").hasKey("content")) { - reqEvent.content = req.data.at("content").at("content").atom; - } - } - - // if we used wget, it will end up here - unify? + { + // if we sent ourself an event it will end up here + // this will call the const subscript operator + if (req.data.at("content").hasKey("_scxmleventname")) { + reqEvent.name = req.data.at("content").at("_scxmleventname").atom; + } + if (req.data.at("content").hasKey("content")) { + reqEvent.content = req.data.at("content").at("content").atom; + } + } + + // if we used wget, it will end up here - unify? if (req.data.hasKey("content")) { const Data& data = req.data["content"]; for(std::map<std::string, Data>::const_iterator compIter = data.compound.begin(); @@ -147,16 +148,16 @@ bool BasicHTTPIOProcessor::httpRecvRequest(const HTTPServer::Request& req) { } } - if (req.data.hasKey("header")) { - const Data& data = req.data["header"]; - for(std::map<std::string, Data>::const_iterator compIter = data.compound.begin(); - compIter!= data.compound.end(); compIter++) { - if (compIter->first == "_scxmleventname") { - reqEvent.name = compIter->second.atom; - } - } - } - + if (req.data.hasKey("header")) { + const Data& data = req.data["header"]; + for(std::map<std::string, Data>::const_iterator compIter = data.compound.begin(); + compIter!= data.compound.end(); compIter++) { + if (compIter->first == "_scxmleventname") { + reqEvent.name = compIter->second.atom; + } + } + } + // check whether we can parse it as XML if (reqEvent.content.length() > 0) { NameSpacingParser parser = NameSpacingParser::fromXML(reqEvent.content); diff --git a/src/uscxml/transform/ChartToC.cpp b/src/uscxml/transform/ChartToC.cpp index 3944b92..2d3f6ba 100644 --- a/src/uscxml/transform/ChartToC.cpp +++ b/src/uscxml/transform/ChartToC.cpp @@ -35,1592 +35,1593 @@ namespace uscxml { using namespace Arabica::DOM; using namespace Arabica::XPath; - + Transformer ChartToC::transform(const Interpreter& other) { - ChartToC* c2c = new ChartToC(other); - - return boost::shared_ptr<TransformerImpl>(c2c); + ChartToC* c2c = new ChartToC(other); + + return boost::shared_ptr<TransformerImpl>(c2c); } ChartToC::ChartToC(const Interpreter& other) : TransformerImpl() { - cloneFrom(other.getImpl()); + cloneFrom(other.getImpl()); } void ChartToC::writeTo(std::ostream& stream) { - _binding = (HAS_ATTR(_scxml, "binding") && iequals(ATTR(_scxml, "binding"), "late") ? LATE : EARLY); - _name = (HAS_ATTR(_scxml, "name") ? ATTR(_scxml, "name") : ""); - - std::set<std::string> elements; - elements.insert(_nsInfo.xmlNSPrefix + "scxml"); - elements.insert(_nsInfo.xmlNSPrefix + "state"); - elements.insert(_nsInfo.xmlNSPrefix + "final"); - elements.insert(_nsInfo.xmlNSPrefix + "parallel"); - elements.insert(_nsInfo.xmlNSPrefix + "history"); - elements.insert(_nsInfo.xmlNSPrefix + "initial"); - elements.insert(_nsInfo.xmlNSPrefix + "parallel"); - _states = inDocumentOrder(elements, _scxml); - - for (int i = 0; i < _states.size(); i++) { - Element<std::string> state(_states[i]); - state.setAttribute("documentOrder", toStr(i)); - if (HAS_ATTR(state, "id")) { - _stateNames[ATTR(state, "id")] = state; - } - } - - elements.clear(); - elements.insert(_nsInfo.xmlNSPrefix + "transition"); - _transitions = inPostFixOrder(elements, _scxml); - - for (int i = 0; i < _transitions.size(); i++) { - Element<std::string> transition(_transitions[i]); - transition.setAttribute("postFixOrder", toStr(i)); - } - - // how many bits do we need to represent the state array? - std::string seperator; - _stateCharArraySize = ceil((float)_states.size() / (float)8); - _stateCharArrayInit = "{"; - for (int i = 0; i < _stateCharArraySize; i++) { - _stateCharArrayInit += seperator + "0"; - seperator = ", "; - } - _stateCharArrayInit += "}"; - - seperator = ""; - _transCharArraySize = ceil((float)_transitions.size() / (float)8); - _transCharArrayInit = "{"; - for (int i = 0; i < _transCharArraySize; i++) { - _transCharArrayInit += seperator + "0"; - seperator = ", "; - } - _transCharArrayInit += "}"; - - writeIncludes(stream); - writeMacros(stream); - writeTypes(stream); - writeElementInfo(stream); - writeExecContent(stream); - writeStates(stream); - writeTransitions(stream); - writeHelpers(stream); - writeFSM(stream); - - // http://stackoverflow.com/questions/2525310/how-to-define-and-work-with-an-array-of-bits-in-c - + _binding = (HAS_ATTR(_scxml, "binding") && iequals(ATTR(_scxml, "binding"), "late") ? LATE : EARLY); + _name = (HAS_ATTR(_scxml, "name") ? ATTR(_scxml, "name") : ""); + + std::set<std::string> elements; + elements.insert(_nsInfo.xmlNSPrefix + "scxml"); + elements.insert(_nsInfo.xmlNSPrefix + "state"); + elements.insert(_nsInfo.xmlNSPrefix + "final"); + elements.insert(_nsInfo.xmlNSPrefix + "parallel"); + elements.insert(_nsInfo.xmlNSPrefix + "history"); + elements.insert(_nsInfo.xmlNSPrefix + "initial"); + elements.insert(_nsInfo.xmlNSPrefix + "parallel"); + _states = inDocumentOrder(elements, _scxml); + + for (int i = 0; i < _states.size(); i++) { + Element<std::string> state(_states[i]); + state.setAttribute("documentOrder", toStr(i)); + if (HAS_ATTR(state, "id")) { + _stateNames[ATTR(state, "id")] = state; + } + } + + elements.clear(); + elements.insert(_nsInfo.xmlNSPrefix + "transition"); + _transitions = inPostFixOrder(elements, _scxml); + + for (int i = 0; i < _transitions.size(); i++) { + Element<std::string> transition(_transitions[i]); + transition.setAttribute("postFixOrder", toStr(i)); + } + + // how many bits do we need to represent the state array? + std::string seperator; + _stateCharArraySize = ceil((float)_states.size() / (float)8); + _stateCharArrayInit = "{"; + for (int i = 0; i < _stateCharArraySize; i++) { + _stateCharArrayInit += seperator + "0"; + seperator = ", "; + } + _stateCharArrayInit += "}"; + + seperator = ""; + _transCharArraySize = ceil((float)_transitions.size() / (float)8); + _transCharArrayInit = "{"; + for (int i = 0; i < _transCharArraySize; i++) { + _transCharArrayInit += seperator + "0"; + seperator = ", "; + } + _transCharArrayInit += "}"; + + writeIncludes(stream); + writeMacros(stream); + writeTypes(stream); + writeElementInfo(stream); + writeExecContent(stream); + writeStates(stream); + writeTransitions(stream); + writeHelpers(stream); + writeFSM(stream); + + // http://stackoverflow.com/questions/2525310/how-to-define-and-work-with-an-array-of-bits-in-c + } void ChartToC::writeIncludes(std::ostream& stream) { - stream << "#include <stdint.h> // explicit types" << std::endl; - stream << "#include <stddef.h> // NULL" << std::endl; - stream << std::endl; + stream << "#include <stdint.h> // explicit types" << std::endl; + stream << "#include <stddef.h> // NULL" << std::endl; + stream << std::endl; } void ChartToC::writeMacros(std::ostream& stream) { - stream << "#define IS_SET(idx, bitset) ((bitset[idx >> 3] & (1 << (idx & 7))) != 0)" << std::endl; - stream << "#define SET_BIT(idx, bitset) bitset[idx >> 3] |= (1 << (idx & 7));" << std::endl; - stream << "#define CLEARBIT(idx, bitset) bitset[idx >> 3] &= (1 << (idx & 7)) ^ 0xFF;" << std::endl; - stream << std::endl; - - stream << "#ifdef __GNUC__" << std::endl; - stream << "#define likely(x) __builtin_expect(!!(x), 1)" << std::endl; - stream << "#define unlikely(x) __builtin_expect(!!(x), 0)" << std::endl; - stream << "#else" << std::endl; - stream << "#define likely(x) (x)" << std::endl; - stream << "#define unlikely(x) (x)" << std::endl; - stream << "#endif" << std::endl; - stream << std::endl; - - stream << "// error return codes" << std::endl; - stream << "#define SCXML_ERR_OK 0" << std::endl; - stream << "#define SCXML_ERR_IDLE 1" << std::endl; - stream << "#define SCXML_ERR_DONE 2" << std::endl; - stream << "#define SCXML_ERR_MISSING_CALLBACK 3" << std::endl; - stream << "#define SCXML_ERR_FOREACH_DONE 4" << std::endl; - stream << "#define SCXML_ERR_EXEC_CONTENT 5" << std::endl; - stream << "#define SCXML_ERR_INVALID_TARGET 6" << std::endl; - stream << "#define SCXML_ERR_INVALID_TYPE 7" << std::endl; - stream << "#define SCXML_ERR_UNSUPPORTED 8" << std::endl; - stream << std::endl; - - stream << "#define SCXML_MACHINE_NAME \"" << _name << "\"" << std::endl; - stream << "#define SCXML_NUMBER_STATES " << _states.size() << std::endl; - stream << "#define SCXML_NUMBER_TRANSITIONS " << _transitions.size() << std::endl; - stream << std::endl; - - stream << "#define SCXML_TRANS_SPONTANEOUS 0x01" << std::endl; - stream << "#define SCXML_TRANS_TARGETLESS 0x02" << std::endl; - stream << "#define SCXML_TRANS_INTERNAL 0x04" << std::endl; - stream << "#define SCXML_TRANS_HISTORY 0x08" << std::endl; - stream << std::endl; - - stream << "#define SCXML_STATE_ATOMIC 0x01" << std::endl; - stream << "#define SCXML_STATE_PARALLEL 0x02" << std::endl; - stream << "#define SCXML_STATE_COMPOUND 0x03" << std::endl; - stream << "#define SCXML_STATE_FINAL 0x04" << std::endl; - stream << "#define SCXML_STATE_HISTORY_DEEP 0x05" << std::endl; - stream << "#define SCXML_STATE_HISTORY_SHALLOW 0x06" << std::endl; - stream << "#define SCXML_STATE_INITIAL 0x07" << std::endl; - - stream << "" << std::endl; - stream << "#define SCXML_CTX_PRISTINE 0x00" << std::endl; - stream << "#define SCXML_CTX_SPONTANEOUS 0x01" << std::endl; - stream << "#define SCXML_CTX_INITIALIZED 0x02" << std::endl; - stream << "#define SCXML_CTX_TOP_LEVEL_FINAL 0x04" << std::endl; - stream << "#define SCXML_CTX_TRANSITION_FOUND 0x08" << std::endl; - stream << std::endl; - - stream << "#define ELEM_DATA_IS_SET(data) (data->id != NULL)" << std::endl; - stream << "#define ELEM_DONEDATA_IS_SET(donedata) (donedata->content != NULL || donedata->contentexpr != NULL || donedata->params != NULL)" << std::endl; - stream << "#define ELEM_PARAM_IS_SET(param) (param->name != NULL)" << std::endl; - stream << std::endl; + stream << "#define IS_SET(idx, bitset) ((bitset[idx >> 3] & (1 << (idx & 7))) != 0)" << std::endl; + stream << "#define SET_BIT(idx, bitset) bitset[idx >> 3] |= (1 << (idx & 7));" << std::endl; + stream << "#define CLEARBIT(idx, bitset) bitset[idx >> 3] &= (1 << (idx & 7)) ^ 0xFF;" << std::endl; + stream << std::endl; + + stream << "#ifdef __GNUC__" << std::endl; + stream << "#define likely(x) __builtin_expect(!!(x), 1)" << std::endl; + stream << "#define unlikely(x) __builtin_expect(!!(x), 0)" << std::endl; + stream << "#else" << std::endl; + stream << "#define likely(x) (x)" << std::endl; + stream << "#define unlikely(x) (x)" << std::endl; + stream << "#endif" << std::endl; + stream << std::endl; + + stream << "// error return codes" << std::endl; + stream << "#define SCXML_ERR_OK 0" << std::endl; + stream << "#define SCXML_ERR_IDLE 1" << std::endl; + stream << "#define SCXML_ERR_DONE 2" << std::endl; + stream << "#define SCXML_ERR_MISSING_CALLBACK 3" << std::endl; + stream << "#define SCXML_ERR_FOREACH_DONE 4" << std::endl; + stream << "#define SCXML_ERR_EXEC_CONTENT 5" << std::endl; + stream << "#define SCXML_ERR_INVALID_TARGET 6" << std::endl; + stream << "#define SCXML_ERR_INVALID_TYPE 7" << std::endl; + stream << "#define SCXML_ERR_UNSUPPORTED 8" << std::endl; + stream << std::endl; + + stream << "#define SCXML_MACHINE_NAME \"" << _name << "\"" << std::endl; + stream << "#define SCXML_NUMBER_STATES " << _states.size() << std::endl; + stream << "#define SCXML_NUMBER_TRANSITIONS " << _transitions.size() << std::endl; + stream << std::endl; + + stream << "#define SCXML_TRANS_SPONTANEOUS 0x01" << std::endl; + stream << "#define SCXML_TRANS_TARGETLESS 0x02" << std::endl; + stream << "#define SCXML_TRANS_INTERNAL 0x04" << std::endl; + stream << "#define SCXML_TRANS_HISTORY 0x08" << std::endl; + stream << std::endl; + + stream << "#define SCXML_STATE_ATOMIC 0x01" << std::endl; + stream << "#define SCXML_STATE_PARALLEL 0x02" << std::endl; + stream << "#define SCXML_STATE_COMPOUND 0x03" << std::endl; + stream << "#define SCXML_STATE_FINAL 0x04" << std::endl; + stream << "#define SCXML_STATE_HISTORY_DEEP 0x05" << std::endl; + stream << "#define SCXML_STATE_HISTORY_SHALLOW 0x06" << std::endl; + stream << "#define SCXML_STATE_INITIAL 0x07" << std::endl; + + stream << "" << std::endl; + stream << "#define SCXML_CTX_PRISTINE 0x00" << std::endl; + stream << "#define SCXML_CTX_SPONTANEOUS 0x01" << std::endl; + stream << "#define SCXML_CTX_INITIALIZED 0x02" << std::endl; + stream << "#define SCXML_CTX_TOP_LEVEL_FINAL 0x04" << std::endl; + stream << "#define SCXML_CTX_TRANSITION_FOUND 0x08" << std::endl; + stream << std::endl; + + stream << "#define ELEM_DATA_IS_SET(data) (data->id != NULL)" << std::endl; + stream << "#define ELEM_DONEDATA_IS_SET(donedata) (donedata->content != NULL || donedata->contentexpr != NULL || donedata->params != NULL)" << std::endl; + stream << "#define ELEM_PARAM_IS_SET(param) (param->name != NULL)" << std::endl; + stream << std::endl; } void ChartToC::writeTypes(std::ostream& stream) { - - stream << std::endl; - stream << "typedef struct scxml_transition scxml_transition;" << std::endl; - stream << "typedef struct scxml_state scxml_state;" << std::endl; - stream << "typedef struct scxml_ctx scxml_ctx;" << std::endl; - stream << "typedef struct scxml_invoke scxml_invoke;" << std::endl; - - stream << std::endl; - - stream << "typedef struct scxml_elem_send scxml_elem_send;" << std::endl; - stream << "typedef struct scxml_elem_param scxml_elem_param;" << std::endl; - stream << "typedef struct scxml_elem_data scxml_elem_data;" << std::endl; - stream << "typedef struct scxml_elem_donedata scxml_elem_donedata;" << std::endl; - stream << "typedef struct scxml_elem_foreach scxml_elem_foreach;" << std::endl; - stream << std::endl; - - stream << "typedef void* (*dequeue_internal_cb_t)(const scxml_ctx* ctx);" << std::endl; - stream << "typedef void* (*dequeue_external_cb_t)(const scxml_ctx* ctx);" << std::endl; - stream << "typedef int (*is_enabled_cb_t)(const scxml_ctx* ctx, const scxml_transition* transition, const void* event);" << std::endl; - stream << "typedef int (*is_true_cb_t)(const scxml_ctx* ctx, const char* expr);" << std::endl; - stream << "typedef int (*exec_content_t)(const scxml_ctx* ctx, const scxml_state* state, const void* event);" << std::endl; - stream << "typedef int (*raise_done_event_t)(const scxml_ctx* ctx, const scxml_state* state, const scxml_elem_donedata* donedata);" << std::endl; - stream << "typedef int (*invoke_t)(const scxml_ctx* ctx, const scxml_state* s, const scxml_invoke* x);" << std::endl; - stream << std::endl; - - stream << "typedef int (*exec_content_log_t)(const scxml_ctx* ctx, const char* label, const char* expr);" << std::endl; - stream << "typedef int (*exec_content_raise_t)(const scxml_ctx* ctx, const char* event);" << std::endl; - stream << "typedef int (*exec_content_send_t)(const scxml_ctx* ctx, const scxml_elem_send* send);" << std::endl; - stream << "typedef int (*exec_content_foreach_init_t)(const scxml_ctx* ctx, const scxml_elem_foreach* foreach);" << std::endl; - stream << "typedef int (*exec_content_foreach_next_t)(const scxml_ctx* ctx, const scxml_elem_foreach* foreach);" << std::endl; - stream << "typedef int (*exec_content_foreach_done_t)(const scxml_ctx* ctx, const scxml_elem_foreach* foreach);" << std::endl; - stream << "typedef int (*exec_content_assign_t)(const scxml_ctx* ctx, const char* location, const char* expr);" << std::endl; - stream << "typedef int (*exec_content_init_t)(const scxml_ctx* ctx, const scxml_elem_data* data);" << std::endl; - stream << "typedef int (*exec_content_cancel_t)(const scxml_ctx* ctx, const char* sendid, const char* sendidexpr);" << std::endl; - stream << "typedef int (*exec_content_finalize_t)(const scxml_ctx* ctx, const scxml_invoke* invoker, const void* event);" << std::endl; - stream << "typedef int (*exec_content_script_t)(const scxml_ctx* ctx, const char* src, const char* content);" << std::endl; - stream << std::endl; - - stream << "struct scxml_elem_data {" << std::endl; - stream << " const char* id;" << std::endl; - stream << " const char* src;" << std::endl; - stream << " const char* expr;" << std::endl; - stream << " const char* content;" << std::endl; - stream << "};" << std::endl; - stream << std::endl; - - stream << "struct scxml_state {" << std::endl; - stream << " const char* name; // eventual name" << std::endl; - stream << " uint16_t source; // parent" << std::endl; - stream << " exec_content_t on_entry; // on entry handlers" << std::endl; - stream << " exec_content_t on_exit; // on exit handlers" << std::endl; - stream << " invoke_t invoke; // invocations" << std::endl; - stream << " char children[" << _stateCharArraySize << "]; // all children" << std::endl; - stream << " char completion[" << _stateCharArraySize << "]; // default completion" << std::endl; - stream << " char ancestors[" << _stateCharArraySize << "]; // all ancestors" << std::endl; - stream << " const scxml_elem_data* data;" << std::endl; - stream << " uint8_t type; // atomic, parallel, compound, final, history" << std::endl; - stream << "};" << std::endl; - stream << std::endl; - - stream << "struct scxml_transition {" << std::endl; - stream << " uint16_t source;" << std::endl; - stream << " char target[" << _stateCharArraySize << "];" << std::endl; - stream << " const char* event;" << std::endl; - stream << " const char* condition;" << std::endl; - stream << " exec_content_t on_transition;" << std::endl; - stream << " uint8_t type;" << std::endl; - stream << " char conflicts[" << _transCharArraySize << "];" << std::endl; - stream << " char exit_set[" << _stateCharArraySize << "];" << std::endl; - stream << "};" << std::endl; - stream << std::endl; - - stream << "struct scxml_elem_foreach {" << std::endl; - stream << " const char* array;" << std::endl; - stream << " const char* item;" << std::endl; - stream << " const char* index;" << std::endl; - stream << "};" << std::endl; - stream << std::endl; - - stream << "struct scxml_elem_param {" << std::endl; - stream << " const char* name;" << std::endl; - stream << " const char* expr;" << std::endl; - stream << " const char* location;" << std::endl; - stream << "};" << std::endl; - stream << std::endl; - - stream << "struct scxml_elem_donedata {" << std::endl; - stream << " uint16_t source;" << std::endl; - stream << " const char* content;" << std::endl; - stream << " const char* contentexpr;" << std::endl; - stream << " const scxml_elem_param* params;" << std::endl; - stream << "};" << std::endl; - stream << std::endl; - - stream << "struct scxml_elem_invoke {" << std::endl; - stream << " const char* type;" << std::endl; - stream << " const char* typeexpr;" << std::endl; - stream << " const char* src;" << std::endl; - stream << " const char* srcexpr;" << std::endl; - stream << " const char* id;" << std::endl; - stream << " const char* idlocation;" << std::endl; - stream << " const char* namelist;" << std::endl; - stream << " uint8_t autoforward;" << std::endl; - stream << " const scxml_elem_param* params;" << std::endl; - stream << " const exec_content_finalize_t* finalize;" << std::endl; - stream << " const char* content;" << std::endl; - stream << " const char* contentexpr;" << std::endl; - stream << " void* user_data;" << std::endl; - stream << "};" << std::endl; - stream << std::endl; - - stream << "struct scxml_elem_send {" << std::endl; - stream << " const char* event;" << std::endl; - stream << " const char* eventexpr;" << std::endl; - stream << " const char* target;" << std::endl; - stream << " const char* targetexpr;" << std::endl; - stream << " const char* type;" << std::endl; - stream << " const char* typeexpr;" << std::endl; - stream << " const char* id;" << std::endl; - stream << " const char* idlocation;" << std::endl; - stream << " const char* delay;" << std::endl; - stream << " const char* delayexpr;" << std::endl; - stream << " const char* namelist;" << std::endl; - stream << " const char* content;" << std::endl; - stream << " const char* contentexpr;" << std::endl; - stream << " const scxml_elem_param* params;" << std::endl; - stream << " void* user_data;" << std::endl; - stream << "};" << std::endl; - stream << std::endl; - - stream << "struct scxml_ctx {" << std::endl; - stream << " uint8_t flags;" << std::endl; - stream << std::endl; - stream << " char config[" << _stateCharArraySize << "];" << std::endl; - stream << " char history[" << _stateCharArraySize << "];" << std::endl; - stream << " char pending_invokes[" << _stateCharArraySize << "];" << std::endl; - stream << " char initialized_data[" << _stateCharArraySize << "];" << std::endl; - stream << std::endl; - stream << " void* user_data;" << std::endl; - stream << std::endl; - stream << " dequeue_internal_cb_t dequeue_internal;" << std::endl; - stream << " dequeue_external_cb_t dequeue_external;" << std::endl; - stream << " is_enabled_cb_t is_enabled;" << std::endl; - stream << " is_true_cb_t is_true;" << std::endl; - stream << " raise_done_event_t raise_done_event;" << std::endl; - stream << std::endl; - stream << " exec_content_log_t exec_content_log;" << std::endl; - stream << " exec_content_raise_t exec_content_raise;" << std::endl; - stream << " exec_content_send_t exec_content_send;" << std::endl; - stream << " exec_content_foreach_init_t exec_content_foreach_init;" << std::endl; - stream << " exec_content_foreach_next_t exec_content_foreach_next;" << std::endl; - stream << " exec_content_foreach_done_t exec_content_foreach_done;" << std::endl; - stream << " exec_content_assign_t exec_content_assign;" << std::endl; - stream << " exec_content_init_t exec_content_init;" << std::endl; - stream << " exec_content_cancel_t exec_content_cancel;" << std::endl; - stream << " exec_content_script_t exec_content_script;" << std::endl; - stream << " invoke_t invoke;" << std::endl; - stream << "};" << std::endl; - stream << std::endl; + + stream << std::endl; + stream << "typedef struct scxml_transition scxml_transition;" << std::endl; + stream << "typedef struct scxml_state scxml_state;" << std::endl; + stream << "typedef struct scxml_ctx scxml_ctx;" << std::endl; + stream << "typedef struct scxml_invoke scxml_invoke;" << std::endl; + + stream << std::endl; + + stream << "typedef struct scxml_elem_send scxml_elem_send;" << std::endl; + stream << "typedef struct scxml_elem_param scxml_elem_param;" << std::endl; + stream << "typedef struct scxml_elem_data scxml_elem_data;" << std::endl; + stream << "typedef struct scxml_elem_donedata scxml_elem_donedata;" << std::endl; + stream << "typedef struct scxml_elem_foreach scxml_elem_foreach;" << std::endl; + stream << std::endl; + + stream << "typedef void* (*dequeue_internal_cb_t)(const scxml_ctx* ctx);" << std::endl; + stream << "typedef void* (*dequeue_external_cb_t)(const scxml_ctx* ctx);" << std::endl; + stream << "typedef int (*is_enabled_cb_t)(const scxml_ctx* ctx, const scxml_transition* transition, const void* event);" << std::endl; + stream << "typedef int (*is_true_cb_t)(const scxml_ctx* ctx, const char* expr);" << std::endl; + stream << "typedef int (*exec_content_t)(const scxml_ctx* ctx, const scxml_state* state, const void* event);" << std::endl; + stream << "typedef int (*raise_done_event_t)(const scxml_ctx* ctx, const scxml_state* state, const scxml_elem_donedata* donedata);" << std::endl; + stream << "typedef int (*invoke_t)(const scxml_ctx* ctx, const scxml_state* s, const scxml_invoke* x);" << std::endl; + stream << std::endl; + + stream << "typedef int (*exec_content_log_t)(const scxml_ctx* ctx, const char* label, const char* expr);" << std::endl; + stream << "typedef int (*exec_content_raise_t)(const scxml_ctx* ctx, const char* event);" << std::endl; + stream << "typedef int (*exec_content_send_t)(const scxml_ctx* ctx, const scxml_elem_send* send);" << std::endl; + stream << "typedef int (*exec_content_foreach_init_t)(const scxml_ctx* ctx, const scxml_elem_foreach* foreach);" << std::endl; + stream << "typedef int (*exec_content_foreach_next_t)(const scxml_ctx* ctx, const scxml_elem_foreach* foreach);" << std::endl; + stream << "typedef int (*exec_content_foreach_done_t)(const scxml_ctx* ctx, const scxml_elem_foreach* foreach);" << std::endl; + stream << "typedef int (*exec_content_assign_t)(const scxml_ctx* ctx, const char* location, const char* expr);" << std::endl; + stream << "typedef int (*exec_content_init_t)(const scxml_ctx* ctx, const scxml_elem_data* data);" << std::endl; + stream << "typedef int (*exec_content_cancel_t)(const scxml_ctx* ctx, const char* sendid, const char* sendidexpr);" << std::endl; + stream << "typedef int (*exec_content_finalize_t)(const scxml_ctx* ctx, const scxml_invoke* invoker, const void* event);" << std::endl; + stream << "typedef int (*exec_content_script_t)(const scxml_ctx* ctx, const char* src, const char* content);" << std::endl; + stream << std::endl; + + stream << "struct scxml_elem_data {" << std::endl; + stream << " const char* id;" << std::endl; + stream << " const char* src;" << std::endl; + stream << " const char* expr;" << std::endl; + stream << " const char* content;" << std::endl; + stream << "};" << std::endl; + stream << std::endl; + + stream << "struct scxml_state {" << std::endl; + stream << " const char* name; // eventual name" << std::endl; + stream << " uint16_t source; // parent" << std::endl; + stream << " exec_content_t on_entry; // on entry handlers" << std::endl; + stream << " exec_content_t on_exit; // on exit handlers" << std::endl; + stream << " invoke_t invoke; // invocations" << std::endl; + stream << " char children[" << _stateCharArraySize << "]; // all children" << std::endl; + stream << " char completion[" << _stateCharArraySize << "]; // default completion" << std::endl; + stream << " char ancestors[" << _stateCharArraySize << "]; // all ancestors" << std::endl; + stream << " const scxml_elem_data* data;" << std::endl; + stream << " uint8_t type; // atomic, parallel, compound, final, history" << std::endl; + stream << "};" << std::endl; + stream << std::endl; + + stream << "struct scxml_transition {" << std::endl; + stream << " uint16_t source;" << std::endl; + stream << " char target[" << _stateCharArraySize << "];" << std::endl; + stream << " const char* event;" << std::endl; + stream << " const char* condition;" << std::endl; + stream << " exec_content_t on_transition;" << std::endl; + stream << " uint8_t type;" << std::endl; + stream << " char conflicts[" << _transCharArraySize << "];" << std::endl; + stream << " char exit_set[" << _stateCharArraySize << "];" << std::endl; + stream << "};" << std::endl; + stream << std::endl; + + stream << "struct scxml_elem_foreach {" << std::endl; + stream << " const char* array;" << std::endl; + stream << " const char* item;" << std::endl; + stream << " const char* index;" << std::endl; + stream << "};" << std::endl; + stream << std::endl; + + stream << "struct scxml_elem_param {" << std::endl; + stream << " const char* name;" << std::endl; + stream << " const char* expr;" << std::endl; + stream << " const char* location;" << std::endl; + stream << "};" << std::endl; + stream << std::endl; + + stream << "struct scxml_elem_donedata {" << std::endl; + stream << " uint16_t source;" << std::endl; + stream << " const char* content;" << std::endl; + stream << " const char* contentexpr;" << std::endl; + stream << " const scxml_elem_param* params;" << std::endl; + stream << "};" << std::endl; + stream << std::endl; + + stream << "struct scxml_elem_invoke {" << std::endl; + stream << " const char* type;" << std::endl; + stream << " const char* typeexpr;" << std::endl; + stream << " const char* src;" << std::endl; + stream << " const char* srcexpr;" << std::endl; + stream << " const char* id;" << std::endl; + stream << " const char* idlocation;" << std::endl; + stream << " const char* namelist;" << std::endl; + stream << " uint8_t autoforward;" << std::endl; + stream << " const scxml_elem_param* params;" << std::endl; + stream << " const exec_content_finalize_t* finalize;" << std::endl; + stream << " const char* content;" << std::endl; + stream << " const char* contentexpr;" << std::endl; + stream << " void* user_data;" << std::endl; + stream << "};" << std::endl; + stream << std::endl; + + stream << "struct scxml_elem_send {" << std::endl; + stream << " const char* event;" << std::endl; + stream << " const char* eventexpr;" << std::endl; + stream << " const char* target;" << std::endl; + stream << " const char* targetexpr;" << std::endl; + stream << " const char* type;" << std::endl; + stream << " const char* typeexpr;" << std::endl; + stream << " const char* id;" << std::endl; + stream << " const char* idlocation;" << std::endl; + stream << " const char* delay;" << std::endl; + stream << " const char* delayexpr;" << std::endl; + stream << " const char* namelist;" << std::endl; + stream << " const char* content;" << std::endl; + stream << " const char* contentexpr;" << std::endl; + stream << " const scxml_elem_param* params;" << std::endl; + stream << " void* user_data;" << std::endl; + stream << "};" << std::endl; + stream << std::endl; + + stream << "struct scxml_ctx {" << std::endl; + stream << " uint8_t flags;" << std::endl; + stream << std::endl; + stream << " char config[" << _stateCharArraySize << "];" << std::endl; + stream << " char history[" << _stateCharArraySize << "];" << std::endl; + stream << " char pending_invokes[" << _stateCharArraySize << "];" << std::endl; + stream << " char initialized_data[" << _stateCharArraySize << "];" << std::endl; + stream << std::endl; + stream << " void* user_data;" << std::endl; + stream << std::endl; + stream << " dequeue_internal_cb_t dequeue_internal;" << std::endl; + stream << " dequeue_external_cb_t dequeue_external;" << std::endl; + stream << " is_enabled_cb_t is_enabled;" << std::endl; + stream << " is_true_cb_t is_true;" << std::endl; + stream << " raise_done_event_t raise_done_event;" << std::endl; + stream << std::endl; + stream << " exec_content_log_t exec_content_log;" << std::endl; + stream << " exec_content_raise_t exec_content_raise;" << std::endl; + stream << " exec_content_send_t exec_content_send;" << std::endl; + stream << " exec_content_foreach_init_t exec_content_foreach_init;" << std::endl; + stream << " exec_content_foreach_next_t exec_content_foreach_next;" << std::endl; + stream << " exec_content_foreach_done_t exec_content_foreach_done;" << std::endl; + stream << " exec_content_assign_t exec_content_assign;" << std::endl; + stream << " exec_content_init_t exec_content_init;" << std::endl; + stream << " exec_content_cancel_t exec_content_cancel;" << std::endl; + stream << " exec_content_script_t exec_content_script;" << std::endl; + stream << " invoke_t invoke;" << std::endl; + stream << "};" << std::endl; + stream << std::endl; } void ChartToC::writeHelpers(std::ostream& stream) { - stream << "#ifdef SCXML_VERBOSE" << std::endl; - stream << "static void printStateNames(const char* a) {" << std::endl; - stream << " const char* seperator = \"\";" << std::endl; - stream << " for (int i = 0; i < SCXML_NUMBER_STATES; i++) {" << std::endl; - stream << " if (IS_SET(i, a)) {" << std::endl; - stream << " printf(\"%s%s\", seperator, (scxml_states[i].name != NULL ? scxml_states[i].name : \"UNK\"));" << std::endl; - stream << " seperator = \", \";" << std::endl; - stream << " }" << std::endl; - stream << " }" << std::endl; - stream << " printf(\"\\n\");" << std::endl; - stream << "}" << std::endl; - stream << std::endl; - - stream << "static void printBitsetIndices(const char* a, size_t length) {" << std::endl; - stream << " const char* seperator = \"\";" << std::endl; - stream << " for (int i = 0; i < length; i++) {" << std::endl; - stream << " if (IS_SET(i, a)) {" << std::endl; - stream << " printf(\"%s%d\", seperator, i);" << std::endl; - stream << " seperator = \", \";" << std::endl; - stream << " }" << std::endl; - stream << " }" << std::endl; - stream << " printf(\"\\n\");" << std::endl; - stream << "}" << std::endl; - - stream << "#endif" << std::endl; - stream << std::endl; - - stream << "static void bit_or(char* dest, const char* mask, size_t i) {" << std::endl; - stream << " do {" << std::endl; - stream << " dest[i - 1] |= mask[i - 1];" << std::endl; - stream << " } while(--i);" << std::endl; - stream << "}" << std::endl; - stream << std::endl; - - stream << "static void bit_copy(char* dest, const char* source, size_t i) {" << std::endl; - stream << " do {" << std::endl; - stream << " dest[i - 1] = source[i - 1];" << std::endl; - stream << " } while(--i);" << std::endl; - stream << "}" << std::endl; - stream << std::endl; - - stream << "static int bit_has_and(const char* a, const char* b, size_t i) {" << std::endl; - stream << " do {" << std::endl; - stream << " if (a[i - 1] & b[i - 1])" << std::endl; - stream << " return true;" << std::endl; - stream << " } while(--i);" << std::endl; - stream << " return false;" << std::endl; - stream << "}" << std::endl; - stream << std::endl; - - stream << "static void bit_and_not(char* dest, const char* mask, size_t i) {" << std::endl; - stream << " do {" << std::endl; - stream << " dest[i - 1] &= ~mask[i - 1];" << std::endl; - stream << " } while(--i);" << std::endl; - stream << "}" << std::endl; - stream << std::endl; - - stream << "static void bit_and(char* dest, const char* mask, size_t i) {" << std::endl; - stream << " do {" << std::endl; - stream << " dest[i - 1] &= mask[i - 1];" << std::endl; - stream << " } while(--i);" << std::endl; - stream << "}" << std::endl; - stream << std::endl; - - stream << "static int bit_any_set(const char* a, size_t i) {" << std::endl; - stream << " do {" << std::endl; - stream << " if (a[i - 1] > 0)" << std::endl; - stream << " return true;" << std::endl; - stream << " } while(--i);" << std::endl; - stream << " return false;" << std::endl; - stream << "}" << std::endl; - stream << std::endl; + stream << "#ifdef SCXML_VERBOSE" << std::endl; + stream << "static void printStateNames(const char* a) {" << std::endl; + stream << " const char* seperator = \"\";" << std::endl; + stream << " for (int i = 0; i < SCXML_NUMBER_STATES; i++) {" << std::endl; + stream << " if (IS_SET(i, a)) {" << std::endl; + stream << " printf(\"%s%s\", seperator, (scxml_states[i].name != NULL ? scxml_states[i].name : \"UNK\"));" << std::endl; + stream << " seperator = \", \";" << std::endl; + stream << " }" << std::endl; + stream << " }" << std::endl; + stream << " printf(\"\\n\");" << std::endl; + stream << "}" << std::endl; + stream << std::endl; + + stream << "static void printBitsetIndices(const char* a, size_t length) {" << std::endl; + stream << " const char* seperator = \"\";" << std::endl; + stream << " for (int i = 0; i < length; i++) {" << std::endl; + stream << " if (IS_SET(i, a)) {" << std::endl; + stream << " printf(\"%s%d\", seperator, i);" << std::endl; + stream << " seperator = \", \";" << std::endl; + stream << " }" << std::endl; + stream << " }" << std::endl; + stream << " printf(\"\\n\");" << std::endl; + stream << "}" << std::endl; + + stream << "#endif" << std::endl; + stream << std::endl; + + stream << "static void bit_or(char* dest, const char* mask, size_t i) {" << std::endl; + stream << " do {" << std::endl; + stream << " dest[i - 1] |= mask[i - 1];" << std::endl; + stream << " } while(--i);" << std::endl; + stream << "}" << std::endl; + stream << std::endl; + + stream << "static void bit_copy(char* dest, const char* source, size_t i) {" << std::endl; + stream << " do {" << std::endl; + stream << " dest[i - 1] = source[i - 1];" << std::endl; + stream << " } while(--i);" << std::endl; + stream << "}" << std::endl; + stream << std::endl; + + stream << "static int bit_has_and(const char* a, const char* b, size_t i) {" << std::endl; + stream << " do {" << std::endl; + stream << " if (a[i - 1] & b[i - 1])" << std::endl; + stream << " return true;" << std::endl; + stream << " } while(--i);" << std::endl; + stream << " return false;" << std::endl; + stream << "}" << std::endl; + stream << std::endl; + + stream << "static void bit_and_not(char* dest, const char* mask, size_t i) {" << std::endl; + stream << " do {" << std::endl; + stream << " dest[i - 1] &= ~mask[i - 1];" << std::endl; + stream << " } while(--i);" << std::endl; + stream << "}" << std::endl; + stream << std::endl; + + stream << "static void bit_and(char* dest, const char* mask, size_t i) {" << std::endl; + stream << " do {" << std::endl; + stream << " dest[i - 1] &= mask[i - 1];" << std::endl; + stream << " } while(--i);" << std::endl; + stream << "}" << std::endl; + stream << std::endl; + + stream << "static int bit_any_set(const char* a, size_t i) {" << std::endl; + stream << " do {" << std::endl; + stream << " if (a[i - 1] > 0)" << std::endl; + stream << " return true;" << std::endl; + stream << " } while(--i);" << std::endl; + stream << " return false;" << std::endl; + stream << "}" << std::endl; + stream << std::endl; } - + void ChartToC::writeExecContent(std::ostream& stream) { - for (int i = 0; i < _states.size(); i++) { - Element<std::string> state(_states[i]); - - if (i == 0) { - // root state - we need to perform some initialization here - NodeSet<std::string> globalScripts = filterChildElements(_nsInfo.xmlNSPrefix + "script", state); - if (globalScripts.size() > 0) { - _hasGlobalScripts = true; - for (int j = 0; j < globalScripts.size(); j++) { - stream << "static int global_script_" << toStr(j) << "(const scxml_ctx* ctx, const scxml_state* state, const void* event) {" << std::endl; - stream << " int err = SCXML_ERR_OK;" << std::endl; - writeExecContent(stream, globalScripts[j], 1); - stream << " return SCXML_ERR_OK;" << std::endl; - stream << "}" << std::endl; - } - - stream << "static int global_script(const scxml_ctx* ctx, const scxml_state* state, const void* event) {" << std::endl; - for (int j = 0; j < globalScripts.size(); j++) { - stream << " global_script_" << toStr(j) << "(ctx, state, event);" << std::endl; - } - stream << " return SCXML_ERR_OK;" << std::endl; - stream << "}" << std::endl; - stream << std::endl; - } else { - _hasGlobalScripts = false; - } - } - - NodeSet<std::string> onexit = filterChildElements(_nsInfo.xmlNSPrefix + "onexit", state); - for (int j = 0; j < onexit.size(); j++) { - stream << "static int " << DOMUtils::idForNode(state) << "_on_exit_" << toStr(j) << "(const scxml_ctx* ctx, const scxml_state* state, const void* event) {" << std::endl; - stream << " int err = SCXML_ERR_OK;" << std::endl; - writeExecContent(stream, onexit[j], 1); - stream << " return SCXML_ERR_OK;" << std::endl; - stream << "}" << std::endl; - stream << std::endl; - } - - if (onexit.size() > 0) { - stream << "static int " << DOMUtils::idForNode(state) << "_on_exit(const scxml_ctx* ctx, const scxml_state* state, const void* event) {" << std::endl; - for (int j = 0; j < onexit.size(); j++) { - stream << " " << DOMUtils::idForNode(state) << "_on_exit_" << toStr(j) << "(ctx, state, event);" << std::endl; - } - stream << " return SCXML_ERR_OK;" << std::endl; - stream << "}" << std::endl; - stream << std::endl; - } - - - NodeSet<std::string> onentry = filterChildElements(_nsInfo.xmlNSPrefix + "onentry", state); - for (int j = 0; j < onentry.size(); j++) { - stream << "static int " << DOMUtils::idForNode(state) << "_on_entry_" << toStr(j) << "(const scxml_ctx* ctx, const scxml_state* state, const void* event) {" << std::endl; - stream << " int err = SCXML_ERR_OK;" << std::endl; - writeExecContent(stream, onentry[j], 1); - stream << " return SCXML_ERR_OK;" << std::endl; - stream << "}" << std::endl; - stream << std::endl; - } - - bool hasInitialState = false; - NodeSet<std::string> initial = filterChildElements(_nsInfo.xmlNSPrefix + "initial", state); - if (initial.size() > 0) { - NodeSet<std::string> initialTransition = filterChildElements(_nsInfo.xmlNSPrefix + "transition", initial); - if (initialTransition.size() > 0) { - hasInitialState = true; - stream << "static int " << DOMUtils::idForNode(state) << "_initial" << "(const scxml_ctx* ctx, const scxml_state* state, const void* event) {" << std::endl; - stream << " int err = SCXML_ERR_OK;" << std::endl; - writeExecContent(stream, initialTransition[0], 1); - stream << " return SCXML_ERR_OK;" << std::endl; - stream << "}" << std::endl; - stream << std::endl; - } - } - - - if (onentry.size() > 0) { - stream << "static int " << DOMUtils::idForNode(state) << "_on_entry(const scxml_ctx* ctx, const scxml_state* state, const void* event) {" << std::endl; - for (int j = 0; j < onentry.size(); j++) { - stream << " " << DOMUtils::idForNode(state) << "_on_entry_" << toStr(j) << "(ctx, state, event);" << std::endl; - } - if (hasInitialState) { - stream << " " << DOMUtils::idForNode(state) << "_initial" << "(ctx, state, event);" << std::endl; - } - - stream << " return SCXML_ERR_OK;" << std::endl; - stream << "}" << std::endl; - stream << std::endl; - } - - - NodeSet<std::string> invoke = filterChildElements(_nsInfo.xmlNSPrefix + "invoke", state); - if (invoke.size() > 0) { - stream << "static int " << DOMUtils::idForNode(state) << "_invoke(const scxml_ctx* ctx, const scxml_state* s, const scxml_invoke* x) {" << std::endl; - for (int j = 0; j < invoke.size(); j++) { - stream << " ctx->invoke(ctx, s, x);" << std::endl; - stream << " return SCXML_ERR_OK;" << std::endl; - stream << std::endl; - } - stream << "}" << std::endl; - } - } - - for (int i = 0; i < _transitions.size(); i++) { - Element<std::string> transition(_transitions[i]); - if (iequals(TAGNAME_CAST(transition.getParentNode()), "initial")) - continue; - - NodeSet<std::string> execContent = filterChildType(Node_base::ELEMENT_NODE, transition); - - if (execContent.size() > 0) { - stream << "static int " << DOMUtils::idForNode(transition) << "_on_trans(const scxml_ctx* ctx, const scxml_state* state, const void* event) {" << std::endl; - stream << " int err = SCXML_ERR_OK;" << std::endl; - for (int j = 0; j < execContent.size(); j++) { - writeExecContent(stream, Element<std::string>(execContent[j]), 1); - } - stream << " return SCXML_ERR_OK;" << std::endl; - stream << "}" << std::endl; - stream << std::endl; - } - } + for (int i = 0; i < _states.size(); i++) { + Element<std::string> state(_states[i]); + + if (i == 0) { + // root state - we need to perform some initialization here + NodeSet<std::string> globalScripts = filterChildElements(_nsInfo.xmlNSPrefix + "script", state); + if (globalScripts.size() > 0) { + _hasGlobalScripts = true; + for (int j = 0; j < globalScripts.size(); j++) { + stream << "static int global_script_" << toStr(j) << "(const scxml_ctx* ctx, const scxml_state* state, const void* event) {" << std::endl; + stream << " int err = SCXML_ERR_OK;" << std::endl; + writeExecContent(stream, globalScripts[j], 1); + stream << " return SCXML_ERR_OK;" << std::endl; + stream << "}" << std::endl; + } + + stream << "static int global_script(const scxml_ctx* ctx, const scxml_state* state, const void* event) {" << std::endl; + for (int j = 0; j < globalScripts.size(); j++) { + stream << " global_script_" << toStr(j) << "(ctx, state, event);" << std::endl; + } + stream << " return SCXML_ERR_OK;" << std::endl; + stream << "}" << std::endl; + stream << std::endl; + } else { + _hasGlobalScripts = false; + } + } + + NodeSet<std::string> onexit = filterChildElements(_nsInfo.xmlNSPrefix + "onexit", state); + for (int j = 0; j < onexit.size(); j++) { + stream << "static int " << DOMUtils::idForNode(state) << "_on_exit_" << toStr(j) << "(const scxml_ctx* ctx, const scxml_state* state, const void* event) {" << std::endl; + stream << " int err = SCXML_ERR_OK;" << std::endl; + writeExecContent(stream, onexit[j], 1); + stream << " return SCXML_ERR_OK;" << std::endl; + stream << "}" << std::endl; + stream << std::endl; + } + + if (onexit.size() > 0) { + stream << "static int " << DOMUtils::idForNode(state) << "_on_exit(const scxml_ctx* ctx, const scxml_state* state, const void* event) {" << std::endl; + for (int j = 0; j < onexit.size(); j++) { + stream << " " << DOMUtils::idForNode(state) << "_on_exit_" << toStr(j) << "(ctx, state, event);" << std::endl; + } + stream << " return SCXML_ERR_OK;" << std::endl; + stream << "}" << std::endl; + stream << std::endl; + } + + + NodeSet<std::string> onentry = filterChildElements(_nsInfo.xmlNSPrefix + "onentry", state); + for (int j = 0; j < onentry.size(); j++) { + stream << "static int " << DOMUtils::idForNode(state) << "_on_entry_" << toStr(j) << "(const scxml_ctx* ctx, const scxml_state* state, const void* event) {" << std::endl; + stream << " int err = SCXML_ERR_OK;" << std::endl; + writeExecContent(stream, onentry[j], 1); + stream << " return SCXML_ERR_OK;" << std::endl; + stream << "}" << std::endl; + stream << std::endl; + } + + bool hasInitialState = false; + NodeSet<std::string> initial = filterChildElements(_nsInfo.xmlNSPrefix + "initial", state); + if (initial.size() > 0) { + NodeSet<std::string> initialTransition = filterChildElements(_nsInfo.xmlNSPrefix + "transition", initial); + if (initialTransition.size() > 0) { + hasInitialState = true; + stream << "static int " << DOMUtils::idForNode(state) << "_initial" << "(const scxml_ctx* ctx, const scxml_state* state, const void* event) {" << std::endl; + stream << " int err = SCXML_ERR_OK;" << std::endl; + writeExecContent(stream, initialTransition[0], 1); + stream << " return SCXML_ERR_OK;" << std::endl; + stream << "}" << std::endl; + stream << std::endl; + } + } + + + if (onentry.size() > 0) { + stream << "static int " << DOMUtils::idForNode(state) << "_on_entry(const scxml_ctx* ctx, const scxml_state* state, const void* event) {" << std::endl; + for (int j = 0; j < onentry.size(); j++) { + stream << " " << DOMUtils::idForNode(state) << "_on_entry_" << toStr(j) << "(ctx, state, event);" << std::endl; + } + if (hasInitialState) { + stream << " " << DOMUtils::idForNode(state) << "_initial" << "(ctx, state, event);" << std::endl; + } + + stream << " return SCXML_ERR_OK;" << std::endl; + stream << "}" << std::endl; + stream << std::endl; + } + + + NodeSet<std::string> invoke = filterChildElements(_nsInfo.xmlNSPrefix + "invoke", state); + if (invoke.size() > 0) { + stream << "static int " << DOMUtils::idForNode(state) << "_invoke(const scxml_ctx* ctx, const scxml_state* s, const scxml_invoke* x) {" << std::endl; + for (int j = 0; j < invoke.size(); j++) { + stream << " ctx->invoke(ctx, s, x);" << std::endl; + stream << " return SCXML_ERR_OK;" << std::endl; + stream << std::endl; + } + stream << "}" << std::endl; + } + } + + for (int i = 0; i < _transitions.size(); i++) { + Element<std::string> transition(_transitions[i]); + if (iequals(TAGNAME_CAST(transition.getParentNode()), "initial")) + continue; + + NodeSet<std::string> execContent = filterChildType(Node_base::ELEMENT_NODE, transition); + + if (execContent.size() > 0) { + stream << "static int " << DOMUtils::idForNode(transition) << "_on_trans(const scxml_ctx* ctx, const scxml_state* state, const void* event) {" << std::endl; + stream << " int err = SCXML_ERR_OK;" << std::endl; + for (int j = 0; j < execContent.size(); j++) { + writeExecContent(stream, Element<std::string>(execContent[j]), 1); + } + stream << " return SCXML_ERR_OK;" << std::endl; + stream << "}" << std::endl; + stream << std::endl; + } + } } void ChartToC::writeExecContent(std::ostream& stream, const Arabica::DOM::Node<std::string>& node, int indent) { - if (!node) - return; - - if (node.getNodeType() == Node_base::TEXT_NODE) { - if (boost::trim_copy(node.getNodeValue()).length() > 0) { - std::string escaped = escape(node.getNodeValue()); - stream << escaped; - } - return; - } - - std::string padding; - for (int i = 0; i < indent; i++) { - padding += " "; - } - - - if (node.getNodeType() != Node_base::ELEMENT_NODE) - return; // skip anything not an element - - Arabica::DOM::Element<std::string> elem = Arabica::DOM::Element<std::string>(node); - - if (false) { - } else if(TAGNAME(elem) == "onentry" || TAGNAME(elem) == "onexit" || TAGNAME(elem) == "transition" || TAGNAME(elem) == "finalize") { - // descent into childs and write their contents - Arabica::DOM::Node<std::string> child = node.getFirstChild(); - while(child) { - writeExecContent(stream, child, indent); - child = child.getNextSibling(); - } - } else if(TAGNAME(elem) == "script") { - stream << padding; - stream << "if likely(ctx->exec_content_script != NULL) {" << std::endl; - stream << padding; - stream << " if unlikely((err = ctx->exec_content_script(ctx, "; - stream << (HAS_ATTR(elem, "src") ? "\"" + escape(ATTR(elem, "src")) + "\"" : "NULL") << ", "; - - NodeSet<std::string> scriptTexts = filterChildType(Node_base::TEXT_NODE, elem); - if (scriptTexts.size() > 0) { - stream << "\""; - writeExecContent(stream, scriptTexts[0], 0); - stream << "\""; - } else { - stream << "NULL"; - } - - stream << ")) != SCXML_ERR_OK) return err;" << std::endl; - stream << padding << "} else {" << std::endl; - stream << padding << " return SCXML_ERR_MISSING_CALLBACK;" << std::endl; - stream << padding << "}" << std::endl; - - } else if(TAGNAME(elem) == "log") { - stream << padding; - stream << "if likely(ctx->exec_content_log != NULL) {" << std::endl; - stream << padding; - stream << " if unlikely((ctx->exec_content_log(ctx, "; - stream << (HAS_ATTR(elem, "label") ? "\"" + escape(ATTR(elem, "label")) + "\"" : "NULL") << ", "; - stream << (HAS_ATTR(elem, "expr") ? "\"" + escape(ATTR(elem, "expr")) + "\"" : "NULL"); - stream << ")) != SCXML_ERR_OK) return err;" << std::endl; - stream << padding << "} else {" << std::endl; - stream << padding << " return SCXML_ERR_MISSING_CALLBACK;" << std::endl; - stream << padding << "}" << std::endl; - - } else if(TAGNAME(elem) == "foreach") { - stream << padding << "if likely(ctx->exec_content_foreach_init != NULL &&" << std::endl; - stream << padding << " ctx->exec_content_foreach_next != NULL &&" << std::endl; - stream << padding << " ctx->exec_content_foreach_done != NULL) {" << std::endl; - stream << std::endl; - - stream << padding << " if unlikely((ctx->exec_content_foreach_init(ctx, &scxml_elem_foreachs[" << ATTR(elem, "documentOrder") << "])) != SCXML_ERR_OK) return err;" << std::endl; - stream << padding << " while (ctx->exec_content_foreach_next(ctx, &scxml_elem_foreachs[" << ATTR(elem, "documentOrder") << "]) == SCXML_ERR_OK) {" << std::endl; - Arabica::DOM::Node<std::string> child = node.getFirstChild(); - while(child) { - writeExecContent(stream, child, indent + 2); - child = child.getNextSibling(); - } - stream << padding << " }" << std::endl; - stream << padding << " if ((ctx->exec_content_foreach_done(ctx, &scxml_elem_foreachs[" << ATTR(elem, "documentOrder") << "])) != SCXML_ERR_OK) return err;" << std::endl; - stream << padding << "} else {" << std::endl; - stream << padding << " return SCXML_ERR_MISSING_CALLBACK;" << std::endl; - stream << padding << "}" << std::endl; - - } else if(TAGNAME(elem) == "if") { - stream << padding; - stream << "if likely(ctx->is_true != NULL) {" << std::endl; - stream << padding; - stream << " if (ctx->is_true(ctx, " << (HAS_ATTR(elem, "cond") ? "\"" + escape(ATTR(elem, "cond")) + "\"" : "NULL") << ")) {" << std::endl; - Arabica::DOM::Node<std::string> child = elem.getFirstChild(); - while(child) { - if (child.getNodeType() == Node_base::ELEMENT_NODE && TAGNAME_CAST(child) == "elseif") { - stream << padding; - stream << " } else if (ctx->is_true(ctx, " << (HAS_ATTR_CAST(child, "cond") ? "\"" + escape(ATTR_CAST(child, "cond")) + "\"" : "NULL") << ")) {" << std::endl; - } else if (child.getNodeType() == Node_base::ELEMENT_NODE && TAGNAME_CAST(child) == "else") { - stream << padding; - stream << " } else {" << std::endl; - } else { - writeExecContent(stream, child, indent + 2); - } - child = child.getNextSibling(); - } - stream << padding << " }" << std::endl; - stream << padding << "} else {" << std::endl; - stream << padding << " return SCXML_ERR_MISSING_CALLBACK;" << std::endl; - stream << padding << "}" << std::endl; - - } else if(TAGNAME(elem) == "assign") { - stream << padding; - stream << "if likely(ctx->exec_content_assign != NULL) {" << std::endl; - stream << padding; - stream << " if ((ctx->exec_content_assign(ctx, "; - stream << (HAS_ATTR(elem, "location") ? "\"" + escape(ATTR(elem, "location")) + "\"" : "NULL") << ", "; - if (HAS_ATTR(elem, "expr")) { - stream << "\"" + escape(ATTR(elem, "expr")) + "\""; - } else { - NodeSet<std::string> assignTexts = filterChildType(Node_base::TEXT_NODE, elem); - if (assignTexts.size() > 0) { - stream << "\""; - writeExecContent(stream, assignTexts[0], 0); - stream << "\""; - } else { - stream << "NULL"; - } - } - stream << ")) != SCXML_ERR_OK) return err;" << std::endl; - stream << padding << "} else {" << std::endl; - stream << padding << " return SCXML_ERR_MISSING_CALLBACK;" << std::endl; - stream << padding << "}" << std::endl; - - - } else if(TAGNAME(elem) == "raise") { - stream << padding; - stream << "if likely(ctx->exec_content_raise != NULL) {" << std::endl; - stream << padding; - stream << " if unlikely((ctx->exec_content_raise(ctx, "; - stream << (HAS_ATTR(elem, "event") ? "\"" + escape(ATTR(elem, "event")) + "\"" : "NULL"); - stream << ")) != SCXML_ERR_OK) return err;" << std::endl; - stream << padding << "} else {" << std::endl; - stream << padding << " return SCXML_ERR_MISSING_CALLBACK;" << std::endl; - stream << padding << "}" << std::endl; - - } else if(TAGNAME(elem) == "send") { - stream << padding; - stream << "if likely(ctx->exec_content_send != NULL) {" << std::endl; - stream << padding; - stream << " if ((ctx->exec_content_send(ctx, &scxml_elem_sends[" << ATTR(elem, "documentOrder") << "]"; - stream << ")) != SCXML_ERR_OK) return err;" << std::endl; - stream << padding << "} else {" << std::endl; - stream << padding << " return SCXML_ERR_MISSING_CALLBACK;" << std::endl; - stream << padding << "}" << std::endl; - - } else if(TAGNAME(elem) == "cancel") { - stream << padding; - stream << "if likely(ctx->exec_content_cancel != NULL) {" << std::endl; - stream << padding; - stream << " if ((ctx->exec_content_cancel(ctx, "; - stream << (HAS_ATTR(elem, "sendid") ? "\"" + escape(ATTR(elem, "sendid")) + "\"" : "NULL") << ", "; - stream << (HAS_ATTR(elem, "sendidexpr") ? "\"" + escape(ATTR(elem, "sendidexpr")) + "\"" : "NULL"); - stream << ")) != SCXML_ERR_OK) return err;" << std::endl; - stream << padding << "} else {" << std::endl; - stream << padding << " return SCXML_ERR_MISSING_CALLBACK;" << std::endl; - stream << padding << "}" << std::endl; - - } else { - std::cerr << "'" << TAGNAME(elem) << "'" << std::endl << elem << std::endl; - assert(false); - } + if (!node) + return; + + if (node.getNodeType() == Node_base::TEXT_NODE) { + if (boost::trim_copy(node.getNodeValue()).length() > 0) { + std::string escaped = escape(node.getNodeValue()); + stream << escaped; + } + return; + } + + std::string padding; + for (int i = 0; i < indent; i++) { + padding += " "; + } + + + if (node.getNodeType() != Node_base::ELEMENT_NODE) + return; // skip anything not an element + + Arabica::DOM::Element<std::string> elem = Arabica::DOM::Element<std::string>(node); + + if (false) { + } else if(TAGNAME(elem) == "onentry" || TAGNAME(elem) == "onexit" || TAGNAME(elem) == "transition" || TAGNAME(elem) == "finalize") { + // descent into childs and write their contents + Arabica::DOM::Node<std::string> child = node.getFirstChild(); + while(child) { + writeExecContent(stream, child, indent); + child = child.getNextSibling(); + } + } else if(TAGNAME(elem) == "script") { + stream << padding; + stream << "if likely(ctx->exec_content_script != NULL) {" << std::endl; + stream << padding; + stream << " if unlikely((err = ctx->exec_content_script(ctx, "; + stream << (HAS_ATTR(elem, "src") ? "\"" + escape(ATTR(elem, "src")) + "\"" : "NULL") << ", "; + + NodeSet<std::string> scriptTexts = filterChildType(Node_base::TEXT_NODE, elem); + if (scriptTexts.size() > 0) { + stream << "\""; + writeExecContent(stream, scriptTexts[0], 0); + stream << "\""; + } else { + stream << "NULL"; + } + + stream << ")) != SCXML_ERR_OK) return err;" << std::endl; + stream << padding << "} else {" << std::endl; + stream << padding << " return SCXML_ERR_MISSING_CALLBACK;" << std::endl; + stream << padding << "}" << std::endl; + + } else if(TAGNAME(elem) == "log") { + stream << padding; + stream << "if likely(ctx->exec_content_log != NULL) {" << std::endl; + stream << padding; + stream << " if unlikely((ctx->exec_content_log(ctx, "; + stream << (HAS_ATTR(elem, "label") ? "\"" + escape(ATTR(elem, "label")) + "\"" : "NULL") << ", "; + stream << (HAS_ATTR(elem, "expr") ? "\"" + escape(ATTR(elem, "expr")) + "\"" : "NULL"); + stream << ")) != SCXML_ERR_OK) return err;" << std::endl; + stream << padding << "} else {" << std::endl; + stream << padding << " return SCXML_ERR_MISSING_CALLBACK;" << std::endl; + stream << padding << "}" << std::endl; + + } else if(TAGNAME(elem) == "foreach") { + stream << padding << "if likely(ctx->exec_content_foreach_init != NULL &&" << std::endl; + stream << padding << " ctx->exec_content_foreach_next != NULL &&" << std::endl; + stream << padding << " ctx->exec_content_foreach_done != NULL) {" << std::endl; + stream << std::endl; + + stream << padding << " if unlikely((ctx->exec_content_foreach_init(ctx, &scxml_elem_foreachs[" << ATTR(elem, "documentOrder") << "])) != SCXML_ERR_OK) return err;" << std::endl; + stream << padding << " while (ctx->exec_content_foreach_next(ctx, &scxml_elem_foreachs[" << ATTR(elem, "documentOrder") << "]) == SCXML_ERR_OK) {" << std::endl; + Arabica::DOM::Node<std::string> child = node.getFirstChild(); + while(child) { + writeExecContent(stream, child, indent + 2); + child = child.getNextSibling(); + } + stream << padding << " }" << std::endl; + stream << padding << " if ((ctx->exec_content_foreach_done(ctx, &scxml_elem_foreachs[" << ATTR(elem, "documentOrder") << "])) != SCXML_ERR_OK) return err;" << std::endl; + stream << padding << "} else {" << std::endl; + stream << padding << " return SCXML_ERR_MISSING_CALLBACK;" << std::endl; + stream << padding << "}" << std::endl; + + } else if(TAGNAME(elem) == "if") { + stream << padding; + stream << "if likely(ctx->is_true != NULL) {" << std::endl; + stream << padding; + stream << " if (ctx->is_true(ctx, " << (HAS_ATTR(elem, "cond") ? "\"" + escape(ATTR(elem, "cond")) + "\"" : "NULL") << ")) {" << std::endl; + Arabica::DOM::Node<std::string> child = elem.getFirstChild(); + while(child) { + if (child.getNodeType() == Node_base::ELEMENT_NODE && TAGNAME_CAST(child) == "elseif") { + stream << padding; + stream << " } else if (ctx->is_true(ctx, " << (HAS_ATTR_CAST(child, "cond") ? "\"" + escape(ATTR_CAST(child, "cond")) + "\"" : "NULL") << ")) {" << std::endl; + } else if (child.getNodeType() == Node_base::ELEMENT_NODE && TAGNAME_CAST(child) == "else") { + stream << padding; + stream << " } else {" << std::endl; + } else { + writeExecContent(stream, child, indent + 2); + } + child = child.getNextSibling(); + } + stream << padding << " }" << std::endl; + stream << padding << "} else {" << std::endl; + stream << padding << " return SCXML_ERR_MISSING_CALLBACK;" << std::endl; + stream << padding << "}" << std::endl; + + } else if(TAGNAME(elem) == "assign") { + stream << padding; + stream << "if likely(ctx->exec_content_assign != NULL) {" << std::endl; + stream << padding; + stream << " if ((ctx->exec_content_assign(ctx, "; + stream << (HAS_ATTR(elem, "location") ? "\"" + escape(ATTR(elem, "location")) + "\"" : "NULL") << ", "; + if (HAS_ATTR(elem, "expr")) { + stream << "\"" + escape(ATTR(elem, "expr")) + "\""; + } else { + NodeSet<std::string> assignTexts = filterChildType(Node_base::TEXT_NODE, elem); + if (assignTexts.size() > 0) { + stream << "\""; + writeExecContent(stream, assignTexts[0], 0); + stream << "\""; + } else { + stream << "NULL"; + } + } + stream << ")) != SCXML_ERR_OK) return err;" << std::endl; + stream << padding << "} else {" << std::endl; + stream << padding << " return SCXML_ERR_MISSING_CALLBACK;" << std::endl; + stream << padding << "}" << std::endl; + + + } else if(TAGNAME(elem) == "raise") { + stream << padding; + stream << "if likely(ctx->exec_content_raise != NULL) {" << std::endl; + stream << padding; + stream << " if unlikely((ctx->exec_content_raise(ctx, "; + stream << (HAS_ATTR(elem, "event") ? "\"" + escape(ATTR(elem, "event")) + "\"" : "NULL"); + stream << ")) != SCXML_ERR_OK) return err;" << std::endl; + stream << padding << "} else {" << std::endl; + stream << padding << " return SCXML_ERR_MISSING_CALLBACK;" << std::endl; + stream << padding << "}" << std::endl; + + } else if(TAGNAME(elem) == "send") { + stream << padding; + stream << "if likely(ctx->exec_content_send != NULL) {" << std::endl; + stream << padding; + stream << " if ((ctx->exec_content_send(ctx, &scxml_elem_sends[" << ATTR(elem, "documentOrder") << "]"; + stream << ")) != SCXML_ERR_OK) return err;" << std::endl; + stream << padding << "} else {" << std::endl; + stream << padding << " return SCXML_ERR_MISSING_CALLBACK;" << std::endl; + stream << padding << "}" << std::endl; + + } else if(TAGNAME(elem) == "cancel") { + stream << padding; + stream << "if likely(ctx->exec_content_cancel != NULL) {" << std::endl; + stream << padding; + stream << " if ((ctx->exec_content_cancel(ctx, "; + stream << (HAS_ATTR(elem, "sendid") ? "\"" + escape(ATTR(elem, "sendid")) + "\"" : "NULL") << ", "; + stream << (HAS_ATTR(elem, "sendidexpr") ? "\"" + escape(ATTR(elem, "sendidexpr")) + "\"" : "NULL"); + stream << ")) != SCXML_ERR_OK) return err;" << std::endl; + stream << padding << "} else {" << std::endl; + stream << padding << " return SCXML_ERR_MISSING_CALLBACK;" << std::endl; + stream << padding << "}" << std::endl; + + } else { + std::cerr << "'" << TAGNAME(elem) << "'" << std::endl << elem << std::endl; + assert(false); + } } void ChartToC::writeElementInfo(std::ostream& stream) { - NodeSet<std::string> foreachs = filterChildElements(_nsInfo.xmlNSPrefix + "foreach", _scxml, true); - if (foreachs.size() > 0) { - stream << "static scxml_elem_foreach scxml_elem_foreachs[" << foreachs.size() << "] = {" << std::endl; - for (int i = 0; i < foreachs.size(); i++) { - Element<std::string> foreach(foreachs[i]); - stream << " { "; - stream << (HAS_ATTR(foreach, "array") ? "\"" + escape(ATTR(foreach, "array")) + "\"" : "NULL") << ", "; - stream << (HAS_ATTR(foreach, "item") ? "\"" + escape(ATTR(foreach, "item")) + "\"" : "NULL") << ", "; - stream << (HAS_ATTR(foreach, "index") ? "\"" + escape(ATTR(foreach, "index")) + "\"" : "NULL"); - stream << " }" << (i + 1 < foreachs.size() ? ",": "") << std::endl; - foreach.setAttribute("documentOrder", toStr(i)); - } - stream << "};" << std::endl; - stream << std::endl; - } - - NodeSet<std::string> datas = filterChildElements(_nsInfo.xmlNSPrefix + "data", _scxml, true); - if (datas.size() > 0) { - size_t dataIndexOffset = 0; - Node<std::string> parent; - size_t distinctParents = 0; - - if (_binding == InterpreterImpl::EARLY) { - Element<std::string>(_states[0]).setAttribute("dataIndex", "0"); - distinctParents = 1; - } else { - for (int i = 0; i < datas.size(); i++) { - Element<std::string> data(datas[i]); - if (data.getParentNode() != parent) { - distinctParents++; - } - } - } - - parent = Node<std::string>(); - - stream << "static scxml_elem_data scxml_elem_datas[" << datas.size() + distinctParents << "] = {" << std::endl; - for (int i = 0; i < datas.size(); i++) { - Element<std::string> data(datas[i]); - if (data.getParentNode().getParentNode() != parent) { - if (_binding == InterpreterImpl::LATE) { - if (i > 0) { - stream << " { NULL, NULL, NULL, NULL }," << std::endl; - dataIndexOffset++; - } - Element<std::string>(data.getParentNode().getParentNode()).setAttribute("dataIndex", toStr(i + dataIndexOffset)); - } - parent = data.getParentNode().getParentNode(); - } - stream << " { "; - stream << (HAS_ATTR(data, "id") ? "\"" + escape(ATTR(data, "id")) + "\"" : "NULL") << ", "; - stream << (HAS_ATTR(data, "src") ? "\"" + escape(ATTR(data, "src")) + "\"" : "NULL") << ", "; - stream << (HAS_ATTR(data, "expr") ? "\"" + escape(ATTR(data, "expr")) + "\"" : "NULL") << ", "; - - NodeSet<std::string> dataTexts = filterChildType(Node_base::TEXT_NODE, data); - if (dataTexts.size() > 0) { - if (boost::trim_copy(dataTexts[0].getNodeValue()).length() > 0) { - std::string escaped = escape(dataTexts[0].getNodeValue()); - stream << "\"" << escaped << "\"" << std::endl; - } - } else { - stream << "NULL"; - } - stream << " }," << std::endl; - - } - stream << " { NULL, NULL, NULL, NULL }" << std::endl; - stream << "};" << std::endl; - stream << std::endl; - } - - NodeSet<std::string> params = filterChildElements(_nsInfo.xmlNSPrefix + "param", _scxml, true); - if (params.size() > 0) { - Node<std::string> parent; - size_t distinctParents = 0; - for (int i = 0; i < params.size(); i++) { - Element<std::string> param(params[i]); - if (param.getParentNode() != parent) { - distinctParents++; - } - } - parent = Node<std::string>(); - - stream << "static scxml_elem_param scxml_elem_params[" << params.size() + distinctParents << "] = {" << std::endl; - for (int i = 0; i < params.size(); i++) { - Element<std::string> param(params[i]); - if (param.getParentNode() != parent) { - Element<std::string>(param.getParentNode()).setAttribute("paramIndex", toStr(i)); - if (i > 0) { - stream << " { NULL, NULL, NULL }," << std::endl; - } - parent = param.getParentNode(); - } - stream << " { "; - stream << (HAS_ATTR(param, "name") ? "\"" + escape(ATTR(param, "name")) + "\"" : "NULL") << ", "; - stream << (HAS_ATTR(param, "expr") ? "\"" + escape(ATTR(param, "expr")) + "\"" : "NULL") << ", "; - stream << (HAS_ATTR(param, "location") ? "\"" + escape(ATTR(param, "location")) + "\"" : "NULL"); - stream << " }," << std::endl; - - } - stream << " { NULL, NULL, NULL }" << std::endl; - stream << "};" << std::endl; - stream << std::endl; - } - - NodeSet<std::string> sends = filterChildElements(_nsInfo.xmlNSPrefix + "send", _scxml, true); - if (sends.size() > 0) { - stream << "static scxml_elem_send scxml_elem_sends[" << sends.size() << "] = {" << std::endl; - for (int i = 0; i < sends.size(); i++) { - Element<std::string> send(sends[i]); - stream << " { "; - stream << (HAS_ATTR(send, "event") ? "\"" + escape(ATTR(send, "event")) + "\"" : "NULL") << ", "; - stream << (HAS_ATTR(send, "eventexpr") ? "\"" + escape(ATTR(send, "eventexpr")) + "\"" : "NULL") << ", "; - stream << (HAS_ATTR(send, "target") ? "\"" + escape(ATTR(send, "target")) + "\"" : "NULL") << ", "; - stream << (HAS_ATTR(send, "targetexpr") ? "\"" + escape(ATTR(send, "targetexpr")) + "\"" : "NULL") << ", "; - stream << (HAS_ATTR(send, "type") ? "\"" + escape(ATTR(send, "type")) + "\"" : "NULL") << ", "; - stream << (HAS_ATTR(send, "typeexpr") ? "\"" + escape(ATTR(send, "typeexpr")) + "\"" : "NULL") << ", "; - stream << (HAS_ATTR(send, "id") ? "\"" + escape(ATTR(send, "id")) + "\"" : "NULL") << ", "; - stream << (HAS_ATTR(send, "idlocation") ? "\"" + escape(ATTR(send, "idlocation")) + "\"" : "NULL") << ", "; - stream << (HAS_ATTR(send, "delay") ? "\"" + escape(ATTR(send, "delay")) + "\"" : "NULL") << ", "; - stream << (HAS_ATTR(send, "delayexpr") ? "\"" + escape(ATTR(send, "delayexpr")) + "\"" : "NULL") << ", "; - stream << (HAS_ATTR(send, "namelist") ? "\"" + escape(ATTR(send, "namelist")) + "\"" : "NULL") << ", "; - - NodeSet<std::string> contents = filterChildElements(_nsInfo.xmlNSPrefix + "content", send); - if (contents.size() > 0) { - std::stringstream ss; - NodeList<std::string> cChilds = contents[0].getChildNodes(); - for (int j = 0; j < cChilds.getLength(); j++) { - ss << cChilds.item(j); - } - stream << (ss.str().size() > 0 ? "\"" + escape(ss.str()) + "\", " : "NULL, "); - stream << (HAS_ATTR_CAST(contents[0], "expr") ? "\"" + ATTR_CAST(contents[0], "expr") + "\", " : "NULL, "); - } else { - stream << "NULL, NULL, "; - } - - - if (HAS_ATTR(send, "paramIndex")) { - stream << "(const scxml_elem_param*)&scxml_elem_params[" << escape(ATTR(send, "paramIndex")) << "], "; - } else { - stream << "NULL, "; - } - stream << "NULL"; - - stream << " }" << (i + 1 < sends.size() ? ",": "") << std::endl; - send.setAttribute("documentOrder", toStr(i)); - } - stream << "};" << std::endl; - stream << std::endl; - } - - NodeSet<std::string> donedatas = filterChildElements(_nsInfo.xmlNSPrefix + "donedata", _scxml, true); - if (donedatas.size() > 0) { - _hasDoneData = true; - stream << "static scxml_elem_donedata scxml_elem_donedatas[" << donedatas.size() + 1 << "] = {" << std::endl; - for (int i = 0; i < donedatas.size(); i++) { - Element<std::string> donedata(donedatas[i]); - stream << " { "; - - // parent - stream << ATTR_CAST(donedata.getParentNode(), "documentOrder") << ", "; - - NodeSet<std::string> contents = filterChildElements(_nsInfo.xmlNSPrefix + "content", donedata); - if (contents.size() > 0) { - std::stringstream ss; - NodeList<std::string> cChilds = contents[0].getChildNodes(); - for (int j = 0; j < cChilds.getLength(); j++) { - ss << cChilds.item(j); - } - stream << (ss.str().size() > 0 ? "\"" + escape(ss.str()) + "\", " : "NULL, "); - stream << (HAS_ATTR_CAST(contents[0], "expr") ? "\"" + ATTR_CAST(contents[0], "expr") + "\", " : "NULL, "); - } else { - stream << "NULL, NULL, "; - } - - if (HAS_ATTR(donedata, "paramIndex")) { - stream << "(const scxml_elem_param*)&scxml_elem_params[" << escape(ATTR(donedata, "paramIndex")) << "]"; - } else { - stream << "NULL"; - } - - stream << " }," << std::endl; - donedata.setAttribute("documentOrder", toStr(i)); - } - stream << " { 0, NULL, NULL }" << std::endl; - stream << "};" << std::endl; - stream << std::endl; - } else { - _hasDoneData = false; - } + NodeSet<std::string> foreachs = filterChildElements(_nsInfo.xmlNSPrefix + "foreach", _scxml, true); + if (foreachs.size() > 0) { + stream << "static scxml_elem_foreach scxml_elem_foreachs[" << foreachs.size() << "] = {" << std::endl; + for (int i = 0; i < foreachs.size(); i++) { + Element<std::string> foreach(foreachs[i]); + stream << " { "; + stream << (HAS_ATTR(foreach, "array") ? "\"" + escape(ATTR(foreach, "array")) + "\"" : "NULL") << ", "; + stream << (HAS_ATTR(foreach, "item") ? "\"" + escape(ATTR(foreach, "item")) + "\"" : "NULL") << ", "; + stream << (HAS_ATTR(foreach, "index") ? "\"" + escape(ATTR(foreach, "index")) + "\"" : "NULL"); + stream << " }" << (i + 1 < foreachs.size() ? ",": "") << std::endl; + foreach.setAttribute("documentOrder", toStr(i)); + } + stream << "};" << std::endl; + stream << std::endl; + } + + NodeSet<std::string> datas = filterChildElements(_nsInfo.xmlNSPrefix + "data", _scxml, true); + if (datas.size() > 0) { + size_t dataIndexOffset = 0; + Node<std::string> parent; + size_t distinctParents = 0; + + if (_binding == InterpreterImpl::EARLY) { + Element<std::string>(_states[0]).setAttribute("dataIndex", "0"); + distinctParents = 1; + } else { + for (int i = 0; i < datas.size(); i++) { + Element<std::string> data(datas[i]); + if (data.getParentNode() != parent) { + distinctParents++; + } + } + } + + parent = Node<std::string>(); + + stream << "static scxml_elem_data scxml_elem_datas[" << datas.size() + distinctParents << "] = {" << std::endl; + for (int i = 0; i < datas.size(); i++) { + Element<std::string> data(datas[i]); + if (data.getParentNode().getParentNode() != parent) { + if (_binding == InterpreterImpl::LATE) { + if (i > 0) { + stream << " { NULL, NULL, NULL, NULL }," << std::endl; + dataIndexOffset++; + } + Element<std::string>(data.getParentNode().getParentNode()).setAttribute("dataIndex", toStr(i + dataIndexOffset)); + } + parent = data.getParentNode().getParentNode(); + } + stream << " { "; + stream << (HAS_ATTR(data, "id") ? "\"" + escape(ATTR(data, "id")) + "\"" : "NULL") << ", "; + stream << (HAS_ATTR(data, "src") ? "\"" + escape(ATTR(data, "src")) + "\"" : "NULL") << ", "; + stream << (HAS_ATTR(data, "expr") ? "\"" + escape(ATTR(data, "expr")) + "\"" : "NULL") << ", "; + + NodeSet<std::string> dataTexts = filterChildType(Node_base::TEXT_NODE, data); + if (dataTexts.size() > 0) { + if (boost::trim_copy(dataTexts[0].getNodeValue()).length() > 0) { + std::string escaped = escape(dataTexts[0].getNodeValue()); + stream << "\"" << escaped << "\"" << std::endl; + } + } else { + stream << "NULL"; + } + stream << " }," << std::endl; + + } + stream << " { NULL, NULL, NULL, NULL }" << std::endl; + stream << "};" << std::endl; + stream << std::endl; + } + + NodeSet<std::string> params = filterChildElements(_nsInfo.xmlNSPrefix + "param", _scxml, true); + if (params.size() > 0) { + Node<std::string> parent; + size_t distinctParents = 0; + for (int i = 0; i < params.size(); i++) { + Element<std::string> param(params[i]); + if (param.getParentNode() != parent) { + distinctParents++; + } + } + parent = Node<std::string>(); + + stream << "static scxml_elem_param scxml_elem_params[" << params.size() + distinctParents << "] = {" << std::endl; + for (int i = 0; i < params.size(); i++) { + Element<std::string> param(params[i]); + if (param.getParentNode() != parent) { + Element<std::string>(param.getParentNode()).setAttribute("paramIndex", toStr(i)); + if (i > 0) { + stream << " { NULL, NULL, NULL }," << std::endl; + } + parent = param.getParentNode(); + } + stream << " { "; + stream << (HAS_ATTR(param, "name") ? "\"" + escape(ATTR(param, "name")) + "\"" : "NULL") << ", "; + stream << (HAS_ATTR(param, "expr") ? "\"" + escape(ATTR(param, "expr")) + "\"" : "NULL") << ", "; + stream << (HAS_ATTR(param, "location") ? "\"" + escape(ATTR(param, "location")) + "\"" : "NULL"); + stream << " }," << std::endl; + + } + stream << " { NULL, NULL, NULL }" << std::endl; + stream << "};" << std::endl; + stream << std::endl; + } + + NodeSet<std::string> sends = filterChildElements(_nsInfo.xmlNSPrefix + "send", _scxml, true); + if (sends.size() > 0) { + stream << "static scxml_elem_send scxml_elem_sends[" << sends.size() << "] = {" << std::endl; + for (int i = 0; i < sends.size(); i++) { + Element<std::string> send(sends[i]); + stream << " { "; + stream << (HAS_ATTR(send, "event") ? "\"" + escape(ATTR(send, "event")) + "\"" : "NULL") << ", "; + stream << (HAS_ATTR(send, "eventexpr") ? "\"" + escape(ATTR(send, "eventexpr")) + "\"" : "NULL") << ", "; + stream << (HAS_ATTR(send, "target") ? "\"" + escape(ATTR(send, "target")) + "\"" : "NULL") << ", "; + stream << (HAS_ATTR(send, "targetexpr") ? "\"" + escape(ATTR(send, "targetexpr")) + "\"" : "NULL") << ", "; + stream << (HAS_ATTR(send, "type") ? "\"" + escape(ATTR(send, "type")) + "\"" : "NULL") << ", "; + stream << (HAS_ATTR(send, "typeexpr") ? "\"" + escape(ATTR(send, "typeexpr")) + "\"" : "NULL") << ", "; + stream << (HAS_ATTR(send, "id") ? "\"" + escape(ATTR(send, "id")) + "\"" : "NULL") << ", "; + stream << (HAS_ATTR(send, "idlocation") ? "\"" + escape(ATTR(send, "idlocation")) + "\"" : "NULL") << ", "; + stream << (HAS_ATTR(send, "delay") ? "\"" + escape(ATTR(send, "delay")) + "\"" : "NULL") << ", "; + stream << (HAS_ATTR(send, "delayexpr") ? "\"" + escape(ATTR(send, "delayexpr")) + "\"" : "NULL") << ", "; + stream << (HAS_ATTR(send, "namelist") ? "\"" + escape(ATTR(send, "namelist")) + "\"" : "NULL") << ", "; + + NodeSet<std::string> contents = filterChildElements(_nsInfo.xmlNSPrefix + "content", send); + if (contents.size() > 0) { + std::stringstream ss; + NodeList<std::string> cChilds = contents[0].getChildNodes(); + for (int j = 0; j < cChilds.getLength(); j++) { + ss << cChilds.item(j); + } + stream << (ss.str().size() > 0 ? "\"" + escape(ss.str()) + "\", " : "NULL, "); + stream << (HAS_ATTR_CAST(contents[0], "expr") ? "\"" + ATTR_CAST(contents[0], "expr") + "\", " : "NULL, "); + } else { + stream << "NULL, NULL, "; + } + + + if (HAS_ATTR(send, "paramIndex")) { + stream << "(const scxml_elem_param*)&scxml_elem_params[" << escape(ATTR(send, "paramIndex")) << "], "; + } else { + stream << "NULL, "; + } + stream << "NULL"; + + stream << " }" << (i + 1 < sends.size() ? ",": "") << std::endl; + send.setAttribute("documentOrder", toStr(i)); + } + stream << "};" << std::endl; + stream << std::endl; + } + + NodeSet<std::string> donedatas = filterChildElements(_nsInfo.xmlNSPrefix + "donedata", _scxml, true); + if (donedatas.size() > 0) { + _hasDoneData = true; + stream << "static scxml_elem_donedata scxml_elem_donedatas[" << donedatas.size() + 1 << "] = {" << std::endl; + for (int i = 0; i < donedatas.size(); i++) { + Element<std::string> donedata(donedatas[i]); + stream << " { "; + + // parent + stream << ATTR_CAST(donedata.getParentNode(), "documentOrder") << ", "; + + NodeSet<std::string> contents = filterChildElements(_nsInfo.xmlNSPrefix + "content", donedata); + if (contents.size() > 0) { + std::stringstream ss; + NodeList<std::string> cChilds = contents[0].getChildNodes(); + for (int j = 0; j < cChilds.getLength(); j++) { + ss << cChilds.item(j); + } + stream << (ss.str().size() > 0 ? "\"" + escape(ss.str()) + "\", " : "NULL, "); + stream << (HAS_ATTR_CAST(contents[0], "expr") ? "\"" + ATTR_CAST(contents[0], "expr") + "\", " : "NULL, "); + } else { + stream << "NULL, NULL, "; + } + + if (HAS_ATTR(donedata, "paramIndex")) { + stream << "(const scxml_elem_param*)&scxml_elem_params[" << escape(ATTR(donedata, "paramIndex")) << "]"; + } else { + stream << "NULL"; + } + + stream << " }," << std::endl; + donedata.setAttribute("documentOrder", toStr(i)); + } + stream << " { 0, NULL, NULL }" << std::endl; + stream << "};" << std::endl; + stream << std::endl; + } else { + _hasDoneData = false; + } } void ChartToC::writeStates(std::ostream& stream) { - stream << "static scxml_state scxml_states[" << toStr(_states.size()) << "] = {" << std::endl; - for (int i = 0; i < _states.size(); i++) { - Element<std::string> state(_states[i]); - stream << " { "; - - // name - stream << (HAS_ATTR(state, "id") ? "\"" + escape(ATTR(state, "id")) + "\"" : "NULL") << ", "; - - // parent - stream << (i == 0 ? "0" : ATTR_CAST(state.getParentNode(), "documentOrder")) << ", "; - - // onentry - stream << (filterChildElements(_nsInfo.xmlNSPrefix + "onentry", state).size() > 0 ? DOMUtils::idForNode(state) + "_on_entry" : "NULL") << ", "; - - // onexit - stream << (filterChildElements(_nsInfo.xmlNSPrefix + "onexit", state).size() > 0 ? DOMUtils::idForNode(state) + "_on_exit" : "NULL") << ", "; - - // invokers - stream << (filterChildElements(_nsInfo.xmlNSPrefix + "invoke", state).size() > 0 ? DOMUtils::idForNode(state) + "_invoke" : "NULL") << ", "; - - // children - std::string childBools; - std::string childBoolsIdx; - for (int j = 0; j < _states.size(); j++) { - if (_states[j].getParentNode() == state) { - childBools += "1"; - childBoolsIdx += " " + toStr(j); - } else { - childBools += "0"; - } - } - stream << "{ "; - writeCharArrayInitList(stream, childBools); - stream << " /* " << childBools << "," << childBoolsIdx << " */"; - stream << " }, "; - - // default completion - NodeSet<std::string> completion; - if (isHistory(state)) { - bool deep = (HAS_ATTR(state, "type") && iequals(ATTR(state, "type"), "deep")); - for (int j = 0; j < _states.size(); j++) { - if (deep) { - if (isDescendant(_states[j], state.getParentNode()) && !isHistory(Element<std::string>(_states[j]))) { - completion.push_back(_states[j]); - } - } else { - if (_states[j].getParentNode() == state.getParentNode() && !isHistory(Element<std::string>(_states[j]))) { - completion.push_back(_states[j]); - } - } - } - } if (isParallel(state)) { - completion = getChildStates(state); - } else if (state.hasAttribute("initial")) { - completion = getStates(tokenizeIdRefs(state.getAttribute("initial"))); - } else { - NodeSet<std::string> initElems = filterChildElements(_nsInfo.xmlNSPrefix + "initial", state); - if(initElems.size() > 0 && !iequals(ATTR_CAST(initElems[0], "generated"), "true")) { - // initial element is first child - completion.push_back(initElems[0]); - } else { - // first child state - Arabica::XPath::NodeSet<std::string> initStates; - NodeList<std::string> childs = state.getChildNodes(); - for (int i = 0; i < childs.getLength(); i++) { - if (childs.item(i).getNodeType() != Node_base::ELEMENT_NODE) - continue; - if (isState(Element<std::string>(childs.item(i)))) { - completion.push_back(childs.item(i)); - break; - } - } - } - } - - std::string descBools; - std::string descBoolsIdx; - for (int j = 0; j < _states.size(); j++) { - if (isMember(_states[j], completion)) { - descBools += "1"; - descBoolsIdx += " " + toStr(j); - } else { - descBools += "0"; - } - } - stream << "{ "; - writeCharArrayInitList(stream, descBools); - stream << " /* " << descBools << "," << descBoolsIdx << " */"; - stream << " }, "; - - // ancestors - std::string ancBools; - std::string ancBoolsIdx; - for (int j = 0; j < _states.size(); j++) { - if (isDescendant(state, _states[j])) { - ancBools += "1"; - ancBoolsIdx += " " + toStr(j); - } else { - ancBools += "0"; - } - } - stream << "{ "; - writeCharArrayInitList(stream, ancBools); - stream << " /* " << ancBools << "," << ancBoolsIdx << " */"; - stream << " }, "; - - if (HAS_ATTR(state, "dataIndex")) { - stream << "(const scxml_elem_data*)&scxml_elem_datas[" << escape(ATTR(state, "dataIndex")) << "], "; - } else { - stream << "NULL, "; - } - - if (false) { - } else if (iequals(TAGNAME(state), "initial")) { - stream << "SCXML_STATE_INITIAL"; - } else if (isFinal(state)) { - stream << "SCXML_STATE_FINAL"; - } else if (isHistory(state)) { - if (HAS_ATTR(state, "type") && iequals(ATTR(state, "type"), "deep")) { - stream << "SCXML_STATE_HISTORY_DEEP"; - } else { - stream << "SCXML_STATE_HISTORY_SHALLOW"; - } - } else if (isAtomic(state)) { - stream << "SCXML_STATE_ATOMIC"; - } else if (isParallel(state)) { - stream << "SCXML_STATE_PARALLEL"; - } else if (isCompound(state)) { - stream << "SCXML_STATE_COMPOUND"; - } else { // <scxml> - stream << "SCXML_STATE_COMPOUND"; - } - - stream << " }" << (i + 1 < _states.size() ? ",": "") << std::endl; - } - stream << "};" << std::endl; - stream << std::endl; + stream << "static scxml_state scxml_states[" << toStr(_states.size()) << "] = {" << std::endl; + for (int i = 0; i < _states.size(); i++) { + Element<std::string> state(_states[i]); + stream << " { "; + + // name + stream << (HAS_ATTR(state, "id") ? "\"" + escape(ATTR(state, "id")) + "\"" : "NULL") << ", "; + + // parent + stream << (i == 0 ? "0" : ATTR_CAST(state.getParentNode(), "documentOrder")) << ", "; + + // onentry + stream << (filterChildElements(_nsInfo.xmlNSPrefix + "onentry", state).size() > 0 ? DOMUtils::idForNode(state) + "_on_entry" : "NULL") << ", "; + + // onexit + stream << (filterChildElements(_nsInfo.xmlNSPrefix + "onexit", state).size() > 0 ? DOMUtils::idForNode(state) + "_on_exit" : "NULL") << ", "; + + // invokers + stream << (filterChildElements(_nsInfo.xmlNSPrefix + "invoke", state).size() > 0 ? DOMUtils::idForNode(state) + "_invoke" : "NULL") << ", "; + + // children + std::string childBools; + std::string childBoolsIdx; + for (int j = 0; j < _states.size(); j++) { + if (_states[j].getParentNode() == state) { + childBools += "1"; + childBoolsIdx += " " + toStr(j); + } else { + childBools += "0"; + } + } + stream << "{ "; + writeCharArrayInitList(stream, childBools); + stream << " /* " << childBools << "," << childBoolsIdx << " */"; + stream << " }, "; + + // default completion + NodeSet<std::string> completion; + if (isHistory(state)) { + bool deep = (HAS_ATTR(state, "type") && iequals(ATTR(state, "type"), "deep")); + for (int j = 0; j < _states.size(); j++) { + if (deep) { + if (isDescendant(_states[j], state.getParentNode()) && !isHistory(Element<std::string>(_states[j]))) { + completion.push_back(_states[j]); + } + } else { + if (_states[j].getParentNode() == state.getParentNode() && !isHistory(Element<std::string>(_states[j]))) { + completion.push_back(_states[j]); + } + } + } + } + if (isParallel(state)) { + completion = getChildStates(state); + } else if (state.hasAttribute("initial")) { + completion = getStates(tokenizeIdRefs(state.getAttribute("initial"))); + } else { + NodeSet<std::string> initElems = filterChildElements(_nsInfo.xmlNSPrefix + "initial", state); + if(initElems.size() > 0 && !iequals(ATTR_CAST(initElems[0], "generated"), "true")) { + // initial element is first child + completion.push_back(initElems[0]); + } else { + // first child state + Arabica::XPath::NodeSet<std::string> initStates; + NodeList<std::string> childs = state.getChildNodes(); + for (int i = 0; i < childs.getLength(); i++) { + if (childs.item(i).getNodeType() != Node_base::ELEMENT_NODE) + continue; + if (isState(Element<std::string>(childs.item(i)))) { + completion.push_back(childs.item(i)); + break; + } + } + } + } + + std::string descBools; + std::string descBoolsIdx; + for (int j = 0; j < _states.size(); j++) { + if (isMember(_states[j], completion)) { + descBools += "1"; + descBoolsIdx += " " + toStr(j); + } else { + descBools += "0"; + } + } + stream << "{ "; + writeCharArrayInitList(stream, descBools); + stream << " /* " << descBools << "," << descBoolsIdx << " */"; + stream << " }, "; + + // ancestors + std::string ancBools; + std::string ancBoolsIdx; + for (int j = 0; j < _states.size(); j++) { + if (isDescendant(state, _states[j])) { + ancBools += "1"; + ancBoolsIdx += " " + toStr(j); + } else { + ancBools += "0"; + } + } + stream << "{ "; + writeCharArrayInitList(stream, ancBools); + stream << " /* " << ancBools << "," << ancBoolsIdx << " */"; + stream << " }, "; + + if (HAS_ATTR(state, "dataIndex")) { + stream << "(const scxml_elem_data*)&scxml_elem_datas[" << escape(ATTR(state, "dataIndex")) << "], "; + } else { + stream << "NULL, "; + } + + if (false) { + } else if (iequals(TAGNAME(state), "initial")) { + stream << "SCXML_STATE_INITIAL"; + } else if (isFinal(state)) { + stream << "SCXML_STATE_FINAL"; + } else if (isHistory(state)) { + if (HAS_ATTR(state, "type") && iequals(ATTR(state, "type"), "deep")) { + stream << "SCXML_STATE_HISTORY_DEEP"; + } else { + stream << "SCXML_STATE_HISTORY_SHALLOW"; + } + } else if (isAtomic(state)) { + stream << "SCXML_STATE_ATOMIC"; + } else if (isParallel(state)) { + stream << "SCXML_STATE_PARALLEL"; + } else if (isCompound(state)) { + stream << "SCXML_STATE_COMPOUND"; + } else { // <scxml> + stream << "SCXML_STATE_COMPOUND"; + } + + stream << " }" << (i + 1 < _states.size() ? ",": "") << std::endl; + } + stream << "};" << std::endl; + stream << std::endl; } - - + + void ChartToC::writeTransitions(std::ostream& stream) { - stream << "static scxml_transition scxml_transitions[" << toStr(_transitions.size()) << "] = {" << std::endl; - for (int i = 0; i < _transitions.size(); i++) { - Element<std::string> transition(_transitions[i]); - stream << " { "; - - /** - uint16_t source; - target[SCXML_NUMBER_STATES / 8 + 1]; - const char* event; - const char* condition; - exec_content_t on_transition; - uint8_t type; - char conflicts[SCXML_NUMBER_STATES / 8 + 1]; - char exit_set[SCXML_NUMBER_STATES / 8 + 1]; - */ - - // source - stream << ATTR_CAST(transition.getParentNode(), "documentOrder") << ", "; - - // targets - if (HAS_ATTR(transition, "target")) { - std::list<std::string> targets = tokenize(ATTR(transition, "target")); - - std::string targetBools; - for (int j = 0; j < _states.size(); j++) { - Element<std::string> state(_states[j]); - - if (HAS_ATTR(state, "id") && - std::find(targets.begin(), targets.end(), escape(ATTR(state, "id"))) != targets.end()) { - targetBools += "1"; - } else { - targetBools += "0"; - } - } - - stream << "{ "; - writeCharArrayInitList(stream, targetBools); - stream << " /* " << targetBools << " */"; - stream << " }, "; - - } else { - stream << "{ NULL }, "; - } - - // event - stream << (HAS_ATTR(transition, "event") ? "\"" + escape(ATTR(transition, "event")) + "\"" : "NULL") << ", "; - - // condition - stream << (HAS_ATTR(transition, "cond") ? "\"" + escape(ATTR(transition, "cond")) + "\"" : "NULL") << ", "; - - // on transition handlers - if (filterChildType(Arabica::DOM::Node_base::ELEMENT_NODE, transition).size() > 0 && - !iequals(TAGNAME_CAST(transition.getParentNode()), "initial")) { - stream << DOMUtils::idForNode(transition) + "_on_trans, "; - } else { - stream << "NULL, "; - } - - // type - std::string seperator = ""; - if (!HAS_ATTR(transition, "target")) { - stream << seperator << "SCXML_TRANS_TARGETLESS"; - seperator = " | "; - } - - if (HAS_ATTR(transition, "type") && iequals(ATTR(transition, "type"), "internal")) { - stream << seperator << "SCXML_TRANS_INTERNAL"; - seperator = " | "; - } - - if (!HAS_ATTR(transition, "event")) { - stream << seperator << "SCXML_TRANS_SPONTANEOUS"; - seperator = " | "; - } - - if (iequals(TAGNAME_CAST(transition.getParentNode()), "history")) { - stream << seperator << "SCXML_TRANS_HISTORY"; - seperator = " | "; - } - - if (seperator.size() == 0) { - stream << "0"; - } - stream << ", "; - - // conflicts - std::string conflictBools; - for (unsigned int j = 0; j < _transitions.size(); j++) { - Element<std::string> t2(_transitions[j]); - if (hasIntersection(computeExitSet(transition), computeExitSet(t2)) || - (getSourceState(transition) == getSourceState(t2)) || - (isDescendant(getSourceState(transition), getSourceState(t2))) || - (isDescendant(getSourceState(t2), getSourceState(transition)))) { - conflictBools += "1"; - } else { - conflictBools += "0"; - } - } - stream << "{ "; - writeCharArrayInitList(stream, conflictBools); - stream << " /* " << conflictBools << " */"; - stream << " }, "; - - // exit set - std::string exitSetBools; - NodeSet<std::string> exitSet = computeExitSet(transition); - for (unsigned int j = 0; j < _states.size(); j++) { - Element<std::string> state(_states[j]); - if (isMember(state, exitSet)) { - exitSetBools += "1"; - } else { - exitSetBools += "0"; - } - } - stream << "{ "; - writeCharArrayInitList(stream, exitSetBools); - stream << " /* " << exitSetBools << " */"; - stream << " }"; - - stream << " }" << (i + 1 < _transitions.size() ? ",": "") << std::endl; - } - stream << "};" << std::endl; - stream << std::endl; + stream << "static scxml_transition scxml_transitions[" << toStr(_transitions.size()) << "] = {" << std::endl; + for (int i = 0; i < _transitions.size(); i++) { + Element<std::string> transition(_transitions[i]); + stream << " { "; + + /** + uint16_t source; + target[SCXML_NUMBER_STATES / 8 + 1]; + const char* event; + const char* condition; + exec_content_t on_transition; + uint8_t type; + char conflicts[SCXML_NUMBER_STATES / 8 + 1]; + char exit_set[SCXML_NUMBER_STATES / 8 + 1]; + */ + + // source + stream << ATTR_CAST(transition.getParentNode(), "documentOrder") << ", "; + + // targets + if (HAS_ATTR(transition, "target")) { + std::list<std::string> targets = tokenize(ATTR(transition, "target")); + + std::string targetBools; + for (int j = 0; j < _states.size(); j++) { + Element<std::string> state(_states[j]); + + if (HAS_ATTR(state, "id") && + std::find(targets.begin(), targets.end(), escape(ATTR(state, "id"))) != targets.end()) { + targetBools += "1"; + } else { + targetBools += "0"; + } + } + + stream << "{ "; + writeCharArrayInitList(stream, targetBools); + stream << " /* " << targetBools << " */"; + stream << " }, "; + + } else { + stream << "{ NULL }, "; + } + + // event + stream << (HAS_ATTR(transition, "event") ? "\"" + escape(ATTR(transition, "event")) + "\"" : "NULL") << ", "; + + // condition + stream << (HAS_ATTR(transition, "cond") ? "\"" + escape(ATTR(transition, "cond")) + "\"" : "NULL") << ", "; + + // on transition handlers + if (filterChildType(Arabica::DOM::Node_base::ELEMENT_NODE, transition).size() > 0 && + !iequals(TAGNAME_CAST(transition.getParentNode()), "initial")) { + stream << DOMUtils::idForNode(transition) + "_on_trans, "; + } else { + stream << "NULL, "; + } + + // type + std::string seperator = ""; + if (!HAS_ATTR(transition, "target")) { + stream << seperator << "SCXML_TRANS_TARGETLESS"; + seperator = " | "; + } + + if (HAS_ATTR(transition, "type") && iequals(ATTR(transition, "type"), "internal")) { + stream << seperator << "SCXML_TRANS_INTERNAL"; + seperator = " | "; + } + + if (!HAS_ATTR(transition, "event")) { + stream << seperator << "SCXML_TRANS_SPONTANEOUS"; + seperator = " | "; + } + + if (iequals(TAGNAME_CAST(transition.getParentNode()), "history")) { + stream << seperator << "SCXML_TRANS_HISTORY"; + seperator = " | "; + } + + if (seperator.size() == 0) { + stream << "0"; + } + stream << ", "; + + // conflicts + std::string conflictBools; + for (unsigned int j = 0; j < _transitions.size(); j++) { + Element<std::string> t2(_transitions[j]); + if (hasIntersection(computeExitSet(transition), computeExitSet(t2)) || + (getSourceState(transition) == getSourceState(t2)) || + (isDescendant(getSourceState(transition), getSourceState(t2))) || + (isDescendant(getSourceState(t2), getSourceState(transition)))) { + conflictBools += "1"; + } else { + conflictBools += "0"; + } + } + stream << "{ "; + writeCharArrayInitList(stream, conflictBools); + stream << " /* " << conflictBools << " */"; + stream << " }, "; + + // exit set + std::string exitSetBools; + NodeSet<std::string> exitSet = computeExitSet(transition); + for (unsigned int j = 0; j < _states.size(); j++) { + Element<std::string> state(_states[j]); + if (isMember(state, exitSet)) { + exitSetBools += "1"; + } else { + exitSetBools += "0"; + } + } + stream << "{ "; + writeCharArrayInitList(stream, exitSetBools); + stream << " /* " << exitSetBools << " */"; + stream << " }"; + + stream << " }" << (i + 1 < _transitions.size() ? ",": "") << std::endl; + } + stream << "};" << std::endl; + stream << std::endl; } Arabica::XPath::NodeSet<std::string> ChartToC::computeExitSet(const Arabica::DOM::Element<std::string>& transition) { - - NodeSet<std::string> statesToExit; - if (!isTargetless(transition)) { - Arabica::DOM::Node<std::string> domain = getTransitionDomain(transition); - if (!domain) - return statesToExit; - for (unsigned int j = 0; j < _states.size(); j++) { - const Node<std::string>& s = _states[j]; - if (isDescendant(s, domain)) { - statesToExit.push_back(s); - } - } - } - - return statesToExit; + + NodeSet<std::string> statesToExit; + if (!isTargetless(transition)) { + Arabica::DOM::Node<std::string> domain = getTransitionDomain(transition); + if (!domain) + return statesToExit; + for (unsigned int j = 0; j < _states.size(); j++) { + const Node<std::string>& s = _states[j]; + if (isDescendant(s, domain)) { + statesToExit.push_back(s); + } + } + } + + return statesToExit; } void ChartToC::writeCharArrayInitList(std::ostream& stream, const std::string& boolString) { - /** - * 0111 -> 0x08 - * 1111 -> 0x0f - * 1111 1111 -> 0xff - * 1111 1111 1110 -> 0x0f, 0xfd - * - * 76543210 fedcba98 ... - */ - - std::string charArray; - size_t index = 0; - char currChar = 0; - - for (std::string::const_iterator bIter = boolString.begin(); bIter != boolString.end(); bIter++) { - - if (*bIter == '1') { - currChar |= 1 << index; - } - - index++; - if (index == 8) { - charArray += currChar; - currChar = 0; - index = 0; - } - } - - if (index != 0) { - charArray += currChar; - } - - std::string seperator = ""; - for (std::string::const_iterator cIter = charArray.begin(); cIter != charArray.end(); cIter++) { - stream << seperator << "0x" << std::setw(2) << std::setfill('0') << std::hex << int(*cIter & 0xFF); - seperator = ", "; - } + /** + * 0111 -> 0x08 + * 1111 -> 0x0f + * 1111 1111 -> 0xff + * 1111 1111 1110 -> 0x0f, 0xfd + * + * 76543210 fedcba98 ... + */ + + std::string charArray; + size_t index = 0; + char currChar = 0; + + for (std::string::const_iterator bIter = boolString.begin(); bIter != boolString.end(); bIter++) { + + if (*bIter == '1') { + currChar |= 1 << index; + } + + index++; + if (index == 8) { + charArray += currChar; + currChar = 0; + index = 0; + } + } + + if (index != 0) { + charArray += currChar; + } + + std::string seperator = ""; + for (std::string::const_iterator cIter = charArray.begin(); cIter != charArray.end(); cIter++) { + stream << seperator << "0x" << std::setw(2) << std::setfill('0') << std::hex << int(*cIter & 0xFF); + seperator = ", "; + } } void ChartToC::writeFSM(std::ostream& stream) { - stream << "static int scxml_step(scxml_ctx* ctx) {" << std::endl; - stream << std::endl; - - stream << "#ifdef SCXML_VERBOSE" << std::endl; - stream << " printf(\"Config: \");" << std::endl; - stream << " printStateNames(ctx->config);" << std::endl; - stream << "#endif" << std::endl; - stream << std::endl; - - stream << "// MACRO_STEP:" << std::endl; - stream << " ctx->flags &= ~SCXML_CTX_TRANSITION_FOUND;" << std::endl; - stream << std::endl; - - stream << " if (ctx->flags & SCXML_CTX_TOP_LEVEL_FINAL) " << std::endl; - stream << " return SCXML_ERR_DONE; " << std::endl; - stream << std::endl; - - stream << " int err = SCXML_ERR_OK;" << std::endl; - stream << " char conflicts[" << _transCharArraySize << "] = " << _transCharArrayInit << ";" << std::endl; - stream << " char target_set[" << _stateCharArraySize << "] = " << _stateCharArrayInit << ";" << std::endl; - stream << " char exit_set[" << _stateCharArraySize << "] = " << _stateCharArrayInit << ";" << std::endl; - stream << " char trans_set[" << _transCharArraySize << "] = " << _transCharArrayInit << ";" << std::endl; - stream << " char entry_set[" << _stateCharArraySize << "] = " << _stateCharArrayInit << ";" << std::endl; - stream << std::endl; - - stream << " void* event;" << std::endl; - stream << " if unlikely(ctx->flags == SCXML_CTX_PRISTINE) {" << std::endl; - if (_hasGlobalScripts) { - stream << " global_script(ctx, &scxml_states[0], NULL);" << std::endl; - } - stream << " bit_or(target_set, scxml_states[0].completion, " << _stateCharArraySize << ");" << std::endl; - stream << " ctx->flags |= SCXML_CTX_SPONTANEOUS | SCXML_CTX_INITIALIZED;" << std::endl; - stream << " goto COMPLETE_CONFIG;" << std::endl; - stream << " }" << std::endl; - stream << std::endl; - - stream << " if (ctx->flags & SCXML_CTX_SPONTANEOUS) {" << std::endl; - stream << " event = NULL;" << std::endl; - stream << " goto SELECT_TRANSITIONS;" << std::endl; - stream << " }" << std::endl; - stream << " if ((event = ctx->dequeue_internal(ctx)) != NULL) {" << std::endl; - stream << " goto SELECT_TRANSITIONS;" << std::endl; - stream << " }" << std::endl; - stream << " if ((event = ctx->dequeue_external(ctx)) != NULL) {" << std::endl; - - stream << " goto SELECT_TRANSITIONS;" << std::endl; - stream << " }" << std::endl; - stream << std::endl; + stream << "static int scxml_step(scxml_ctx* ctx) {" << std::endl; + stream << std::endl; + + stream << "#ifdef SCXML_VERBOSE" << std::endl; + stream << " printf(\"Config: \");" << std::endl; + stream << " printStateNames(ctx->config);" << std::endl; + stream << "#endif" << std::endl; + stream << std::endl; + + stream << "// MACRO_STEP:" << std::endl; + stream << " ctx->flags &= ~SCXML_CTX_TRANSITION_FOUND;" << std::endl; + stream << std::endl; + + stream << " if (ctx->flags & SCXML_CTX_TOP_LEVEL_FINAL) " << std::endl; + stream << " return SCXML_ERR_DONE; " << std::endl; + stream << std::endl; + + stream << " int err = SCXML_ERR_OK;" << std::endl; + stream << " char conflicts[" << _transCharArraySize << "] = " << _transCharArrayInit << ";" << std::endl; + stream << " char target_set[" << _stateCharArraySize << "] = " << _stateCharArrayInit << ";" << std::endl; + stream << " char exit_set[" << _stateCharArraySize << "] = " << _stateCharArrayInit << ";" << std::endl; + stream << " char trans_set[" << _transCharArraySize << "] = " << _transCharArrayInit << ";" << std::endl; + stream << " char entry_set[" << _stateCharArraySize << "] = " << _stateCharArrayInit << ";" << std::endl; + stream << std::endl; + + stream << " void* event;" << std::endl; + stream << " if unlikely(ctx->flags == SCXML_CTX_PRISTINE) {" << std::endl; + if (_hasGlobalScripts) { + stream << " global_script(ctx, &scxml_states[0], NULL);" << std::endl; + } + stream << " bit_or(target_set, scxml_states[0].completion, " << _stateCharArraySize << ");" << std::endl; + stream << " ctx->flags |= SCXML_CTX_SPONTANEOUS | SCXML_CTX_INITIALIZED;" << std::endl; + stream << " goto COMPLETE_CONFIG;" << std::endl; + stream << " }" << std::endl; + stream << std::endl; + + stream << " if (ctx->flags & SCXML_CTX_SPONTANEOUS) {" << std::endl; + stream << " event = NULL;" << std::endl; + stream << " goto SELECT_TRANSITIONS;" << std::endl; + stream << " }" << std::endl; + stream << " if ((event = ctx->dequeue_internal(ctx)) != NULL) {" << std::endl; + stream << " goto SELECT_TRANSITIONS;" << std::endl; + stream << " }" << std::endl; + stream << " if ((event = ctx->dequeue_external(ctx)) != NULL) {" << std::endl; + + stream << " goto SELECT_TRANSITIONS;" << std::endl; + stream << " }" << std::endl; + stream << std::endl; // HISTORY TRANSITION IS SELECTED BY ACCIDENT! - - stream << "SELECT_TRANSITIONS:" << std::endl; - stream << " for (int i = 0; i < SCXML_NUMBER_TRANSITIONS; i++) {" << std::endl; - stream << " // never select history or initial transitions automatically" << std::endl; - stream << " if unlikely(scxml_transitions[i].type & (SCXML_TRANS_HISTORY | SCXML_TRANS_HISTORY))" << std::endl; - stream << " continue;" << std::endl; - stream << std::endl; - stream << " // is the transition active?" << std::endl; - stream << " if (IS_SET(scxml_transitions[i].source, ctx->config)) {" << std::endl; - stream << " // is it non-conflicting?" << std::endl; - stream << " if (!IS_SET(i, conflicts)) {" << std::endl; - stream << " // is it enabled?" << std::endl; - stream << " if (ctx->is_enabled(ctx, &scxml_transitions[i], event) > 0) {" << std::endl; - stream << " // remember that we found a transition" << std::endl; - stream << " ctx->flags |= SCXML_CTX_TRANSITION_FOUND;" << std::endl; - stream << std::endl; - - stream << " // transitions that are pre-empted" << std::endl; - stream << " bit_or(conflicts, scxml_transitions[i].conflicts, " << _transCharArraySize << ");" << std::endl; - stream << std::endl; - stream << " // states that are directly targeted (resolve as entry-set later)" << std::endl; - stream << " bit_or(target_set, scxml_transitions[i].target, " << _stateCharArraySize << ");" << std::endl; - stream << std::endl; - stream << " // states that will be left" << std::endl; - stream << " bit_or(exit_set, scxml_transitions[i].exit_set, " << _stateCharArraySize << ");" << std::endl; - stream << std::endl; - stream << " SET_BIT(i, trans_set);" << std::endl; - stream << " }" << std::endl; - stream << " }" << std::endl; - stream << " }" << std::endl; - stream << " }" << std::endl; - stream << " bit_and(exit_set, ctx->config, " << _stateCharArraySize << ");" << std::endl; - stream << std::endl; - - stream << " if (ctx->flags & SCXML_CTX_TRANSITION_FOUND) {" << std::endl; - stream << " ctx->flags |= SCXML_CTX_SPONTANEOUS;" << std::endl; - stream << " } else {" << std::endl; - stream << " ctx->flags &= ~SCXML_CTX_SPONTANEOUS;" << std::endl; - stream << " // goto MACRO_STEP;" << std::endl; - stream << " return SCXML_ERR_OK;" << std::endl; - stream << " }" << std::endl; - stream << std::endl; - - stream << "#ifdef SCXML_VERBOSE" << std::endl; - stream << " printf(\"Targets: \");" << std::endl; - stream << " printStateNames(target_set);" << std::endl; - stream << "#endif" << std::endl; - stream << std::endl; - - stream << "// REMEMBER_HISTORY:" << std::endl; - stream << " for (int i = 0; i < SCXML_NUMBER_STATES; i++) {" << std::endl; - stream << " if unlikely(scxml_states[i].type == SCXML_STATE_HISTORY_SHALLOW || scxml_states[i].type == SCXML_STATE_HISTORY_DEEP) {" << std::endl; - stream << " // a history state whose parent is about to be exited" << std::endl; - stream << " if unlikely(IS_SET(scxml_states[i].source, exit_set)) {" << std::endl; - stream << " char history[" << _stateCharArraySize << "] = " << _stateCharArrayInit << ";" << std::endl; - stream << " bit_copy(history, scxml_states[i].completion, " << _stateCharArraySize << ");" << std::endl; - stream << std::endl; - stream << " // set those states who were enabled" << std::endl; - stream << " bit_and(history, ctx->config, " << _stateCharArraySize << ");" << std::endl; - stream << std::endl; - stream << " // clear current history with completion mask" << std::endl; - stream << " bit_and_not(ctx->history, scxml_states[i].completion, " << _stateCharArraySize << ");" << std::endl; - stream << std::endl; - stream << " // set history" << std::endl; - stream << " bit_or(ctx->history, history, " << _stateCharArraySize << ");" << std::endl; - stream << " }" << std::endl; - stream << " }" << std::endl; - stream << " }" << std::endl; - - stream << "#ifdef SCXML_VERBOSE" << std::endl; - stream << " printf(\"Exiting: \");" << std::endl; - stream << " printStateNames(exit_set);" << std::endl; - stream << "#endif" << std::endl; - stream << std::endl; - - stream << "#ifdef SCXML_VERBOSE" << std::endl; - stream << " printf(\"History: \");" << std::endl; - stream << " printStateNames(ctx->history);" << std::endl; - stream << "#endif" << std::endl; - stream << std::endl; - - stream << "// EXIT_STATES:" << std::endl; - stream << " for (int i = SCXML_NUMBER_STATES - 1; i >= 0; i--) {" << std::endl; - stream << " if (IS_SET(i, exit_set) && IS_SET(i, ctx->config)) {" << std::endl; - stream << " // call all on exit handlers" << std::endl; - stream << " if (scxml_states[i].on_exit != NULL) {" << std::endl; - stream << " if unlikely((err = scxml_states[i].on_exit(ctx, &scxml_states[i], event)) != SCXML_ERR_OK)" << std::endl; - stream << " return err;" << std::endl; - stream << " }" << std::endl; - stream << " CLEARBIT(i, ctx->config);" << std::endl; - stream << " }" << std::endl; - stream << " }" << std::endl; - stream << std::endl; - - stream << "COMPLETE_CONFIG:" << std::endl; - stream << " // calculate new entry set" << std::endl; - stream << " bit_copy(entry_set, target_set, " << _stateCharArraySize << ");" << std::endl; - stream << std::endl; - stream << " // iterate for ancestors" << std::endl; - stream << " for (int i = 0; i < SCXML_NUMBER_STATES; i++) {" << std::endl; - stream << " if (IS_SET(i, entry_set)) {" << std::endl; - stream << " bit_or(entry_set, scxml_states[i].ancestors, " << _stateCharArraySize << ");" << std::endl; - stream << " }" << std::endl; - stream << " }" << std::endl; - stream << std::endl; - - stream << "// ADD_DESCENDANTS:" << std::endl; - stream << " // iterate for descendants" << std::endl; - stream << " for (int i = 0; i < SCXML_NUMBER_STATES; i++) {" << std::endl; - stream << " if (IS_SET(i, entry_set)) {" << std::endl; - stream << " switch (scxml_states[i].type) {" << std::endl; - stream << " case SCXML_STATE_PARALLEL: {" << std::endl; - stream << " bit_or(entry_set, scxml_states[i].completion, " << _stateCharArraySize << ");" << std::endl; - stream << " break;" << std::endl; - stream << " }" << std::endl; - stream << " case SCXML_STATE_HISTORY_SHALLOW:" << std::endl; - stream << " case SCXML_STATE_HISTORY_DEEP: {" << std::endl; - stream << " char history_targets[" << _stateCharArraySize << "] = " << _stateCharArrayInit << ";" << std::endl; - stream << " if (!bit_has_and(scxml_states[i].completion, ctx->history, " << _stateCharArraySize << ")) {" << std::endl; - stream << " // nothing set for history, look for a default transition or enter parents completion" << std::endl; - stream << " for (int j = 0; j < SCXML_NUMBER_TRANSITIONS; j++) {" << std::endl; - stream << " if unlikely(scxml_transitions[j].source == i) {" << std::endl; - stream << " bit_or(entry_set, scxml_transitions[j].target, " << _stateCharArraySize << ");" << std::endl; - stream << " SET_BIT(j, trans_set);" << std::endl; - stream << " break;" << std::endl; - stream << " }" << std::endl; - stream << " }" << std::endl; - stream << " // TODO: enter parents default completion here" << std::endl; - stream << " } else {" << std::endl; - stream << " bit_copy(history_targets, scxml_states[i].completion, " << _stateCharArraySize << ");" << std::endl; - stream << " bit_and(history_targets, ctx->history, " << _stateCharArraySize << ");" << std::endl; - stream << " bit_or(entry_set, history_targets, " << _stateCharArraySize << ");" << std::endl; - stream << " }" << std::endl; - stream << " break;" << std::endl; - stream << " }" << std::endl; - stream << " case SCXML_STATE_INITIAL: {" << std::endl; - stream << " for (int j = 0; j < SCXML_NUMBER_TRANSITIONS; j++) {" << std::endl; - stream << " if (scxml_transitions[j].source == i) {" << std::endl; - stream << " SET_BIT(j, trans_set);" << std::endl; - stream << " CLEARBIT(i, entry_set);" << std::endl; - stream << " bit_or(entry_set, scxml_transitions[j].target, " << _stateCharArraySize << ");" << std::endl; - stream << " // one target may have been above, reestablish completion" << std::endl; - stream << " // goto ADD_DESCENDANTS; // initial will have to be first!" << std::endl; - stream << " }" << std::endl; - stream << " }" << std::endl; - stream << " break;" << std::endl; - stream << " }" << std::endl; - stream << " case SCXML_STATE_COMPOUND: { // we need to check whether one child is already in entry_set" << std::endl; - stream << " if (!bit_has_and(entry_set, scxml_states[i].children, " << _stateCharArraySize << ") &&" << std::endl; - stream << " !bit_has_and(ctx->config, scxml_states[i].children, " << _stateCharArraySize << "))" << std::endl; - stream << " {" << std::endl; - stream << " bit_or(entry_set, scxml_states[i].completion, " << _stateCharArraySize << ");" << std::endl; - stream << " }" << std::endl; - stream << " break;" << std::endl; - stream << " }" << std::endl; - stream << " }" << std::endl; - stream << " }" << std::endl; - stream << " }" << std::endl; - stream << std::endl; - - stream << "#ifdef SCXML_VERBOSE" << std::endl; - stream << " printf(\"Transitions: \");" << std::endl; - stream << " printBitsetIndices(trans_set, sizeof(char) * 8 * " << _transCharArraySize << ");" << std::endl; - stream << "#endif" << std::endl; - stream << std::endl; - - stream << "// TAKE_TRANSITIONS:" << std::endl; - stream << " for (int i = 0; i < SCXML_NUMBER_TRANSITIONS; i++) {" << std::endl; - stream << " if (IS_SET(i, trans_set) && (scxml_transitions[i].type & SCXML_TRANS_HISTORY) == 0) {" << std::endl; - stream << " // call executable content in transition" << std::endl; - stream << " if (scxml_transitions[i].on_transition != NULL) {" << std::endl; - stream << " if unlikely((err = scxml_transitions[i].on_transition(ctx," << std::endl; - stream << " &scxml_states[scxml_transitions[i].source]," << std::endl; - stream << " event)) != SCXML_ERR_OK)" << std::endl; - stream << " return err;" << std::endl; - stream << " }" << std::endl; - stream << " }" << std::endl; - stream << " }" << std::endl; - stream << std::endl; - - stream << "#ifdef SCXML_VERBOSE" << std::endl; - stream << " printf(\"Entering: \");" << std::endl; - stream << " printStateNames(entry_set);" << std::endl; - stream << "#endif" << std::endl; - stream << std::endl; - - stream << "// ENTER_STATES:" << std::endl; - stream << " for (int i = 0; i < SCXML_NUMBER_STATES; i++) {" << std::endl; - stream << " if (IS_SET(i, entry_set) && !IS_SET(i, ctx->config)) {" << std::endl; - stream << " // these are no proper states" << std::endl; - stream << " if unlikely(scxml_states[i].type == SCXML_STATE_HISTORY_DEEP ||" << std::endl; - stream << " scxml_states[i].type == SCXML_STATE_HISTORY_SHALLOW ||" << std::endl; - stream << " scxml_states[i].type == SCXML_STATE_INITIAL)" << std::endl; - stream << " continue;" << std::endl; - stream << std::endl; - - stream << " SET_BIT(i, ctx->config);" << std::endl; - stream << std::endl; - - stream << " // initialize data" << std::endl; - stream << " if (!IS_SET(i, ctx->initialized_data)) {" << std::endl; - stream << " if unlikely(scxml_states[i].data != NULL && ctx->exec_content_init != NULL) {" << std::endl; - stream << " ctx->exec_content_init(ctx, scxml_states[i].data);" << std::endl; - stream << " }" << std::endl; - stream << " SET_BIT(i, ctx->initialized_data);" << std::endl; - stream << " }" << std::endl; - stream << std::endl; - - stream << " if (scxml_states[i].on_entry != NULL) {" << std::endl; - stream << " if unlikely((err = scxml_states[i].on_entry(ctx, &scxml_states[i], event)) != SCXML_ERR_OK)" << std::endl; - stream << " return err;" << std::endl; - stream << " }" << std::endl; - stream << std::endl; - - stream << " // handle final states" << std::endl; - stream << " if unlikely(scxml_states[i].type == SCXML_STATE_FINAL) {" << std::endl; - stream << " if unlikely(scxml_states[i].ancestors[0] == 0x01) {" << std::endl; - stream << " ctx->flags |= SCXML_CTX_TOP_LEVEL_FINAL;" << std::endl; - stream << " } else {" << std::endl; - stream << " // raise done event" << std::endl; - stream << " size_t parent = 0;" << std::endl; - stream << " for (int j = SCXML_NUMBER_STATES - 1; j >= 0; j--) {" << std::endl; - stream << " // we could trade runtime for memory here by saving the parent index" << std::endl; - stream << " if unlikely(IS_SET(j, scxml_states[i].ancestors)) {" << std::endl; - stream << " parent = j;" << std::endl; - stream << " break;" << std::endl; - stream << " }" << std::endl; - stream << " }" << std::endl; - stream << " // is this raised for toplevel final as well?" << std::endl; - if (_hasDoneData) { - stream << " scxml_elem_donedata* donedata = &scxml_elem_donedatas[0];" << std::endl; - stream << " while(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, &scxml_states[parent], (ELEM_DONEDATA_IS_SET(donedata) ? donedata : NULL));" << std::endl; - } else { - stream << " ctx->raise_done_event(ctx, &scxml_states[parent], NULL);" << std::endl; - } - stream << " }" << std::endl; - 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 (int j = 0; j < SCXML_NUMBER_STATES; j++) {" << std::endl; - stream << " if unlikely(scxml_states[j].type == SCXML_STATE_PARALLEL) {" << std::endl; - stream << " char parallel_children[" << _stateCharArraySize << "] = " << _stateCharArrayInit << ";" << std::endl; - stream << " size_t parallel = j;" << std::endl; - stream << " for (int k = 0; k < SCXML_NUMBER_STATES; k++) {" << std::endl; - stream << " if unlikely(IS_SET(parallel, scxml_states[k].ancestors) && IS_SET(k, ctx->config)) {" << std::endl; - stream << " if (scxml_states[k].type == SCXML_STATE_FINAL) {" << std::endl; - stream << " bit_and_not(parallel_children, scxml_states[k].ancestors, " << _stateCharArraySize << ");" << std::endl; - stream << " } else {" << std::endl; - stream << " SET_BIT(k, parallel_children);" << std::endl; - stream << " }" << std::endl; - stream << " }" << std::endl; - stream << " }" << std::endl; - stream << " if unlikely(!bit_any_set(parallel_children, " << _stateCharArraySize << ")) {" << std::endl; - stream << " ctx->raise_done_event(ctx, &scxml_states[parallel], 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 << " }" << std::endl; - stream << std::endl; - - stream << "// HISTORY_TRANSITIONS:" << std::endl; - stream << " for (int i = 0; i < SCXML_NUMBER_TRANSITIONS; i++) {" << std::endl; - stream << " if unlikely(IS_SET(i, trans_set) && (scxml_transitions[i].type & SCXML_TRANS_HISTORY)) {" << std::endl; - stream << " // call executable content in transition" << std::endl; - stream << " if (scxml_transitions[i].on_transition != NULL) {" << std::endl; - stream << " if unlikely((err = scxml_transitions[i].on_transition(ctx," << std::endl; - stream << " &scxml_states[scxml_transitions[i].source]," << std::endl; - stream << " event)) != SCXML_ERR_OK)" << std::endl; - stream << " return err;" << std::endl; - stream << " }" << std::endl; - stream << " }" << std::endl; - stream << " }" << std::endl; - stream << std::endl; - - - stream << " return SCXML_ERR_OK;" << std::endl; - stream << "}" << std::endl; - stream << std::endl; + + stream << "SELECT_TRANSITIONS:" << std::endl; + stream << " for (int i = 0; i < SCXML_NUMBER_TRANSITIONS; i++) {" << std::endl; + stream << " // never select history or initial transitions automatically" << std::endl; + stream << " if unlikely(scxml_transitions[i].type & (SCXML_TRANS_HISTORY | SCXML_TRANS_HISTORY))" << std::endl; + stream << " continue;" << std::endl; + stream << std::endl; + stream << " // is the transition active?" << std::endl; + stream << " if (IS_SET(scxml_transitions[i].source, ctx->config)) {" << std::endl; + stream << " // is it non-conflicting?" << std::endl; + stream << " if (!IS_SET(i, conflicts)) {" << std::endl; + stream << " // is it enabled?" << std::endl; + stream << " if (ctx->is_enabled(ctx, &scxml_transitions[i], event) > 0) {" << std::endl; + stream << " // remember that we found a transition" << std::endl; + stream << " ctx->flags |= SCXML_CTX_TRANSITION_FOUND;" << std::endl; + stream << std::endl; + + stream << " // transitions that are pre-empted" << std::endl; + stream << " bit_or(conflicts, scxml_transitions[i].conflicts, " << _transCharArraySize << ");" << std::endl; + stream << std::endl; + stream << " // states that are directly targeted (resolve as entry-set later)" << std::endl; + stream << " bit_or(target_set, scxml_transitions[i].target, " << _stateCharArraySize << ");" << std::endl; + stream << std::endl; + stream << " // states that will be left" << std::endl; + stream << " bit_or(exit_set, scxml_transitions[i].exit_set, " << _stateCharArraySize << ");" << std::endl; + stream << std::endl; + stream << " SET_BIT(i, trans_set);" << std::endl; + stream << " }" << std::endl; + stream << " }" << std::endl; + stream << " }" << std::endl; + stream << " }" << std::endl; + stream << " bit_and(exit_set, ctx->config, " << _stateCharArraySize << ");" << std::endl; + stream << std::endl; + + stream << " if (ctx->flags & SCXML_CTX_TRANSITION_FOUND) {" << std::endl; + stream << " ctx->flags |= SCXML_CTX_SPONTANEOUS;" << std::endl; + stream << " } else {" << std::endl; + stream << " ctx->flags &= ~SCXML_CTX_SPONTANEOUS;" << std::endl; + stream << " // goto MACRO_STEP;" << std::endl; + stream << " return SCXML_ERR_OK;" << std::endl; + stream << " }" << std::endl; + stream << std::endl; + + stream << "#ifdef SCXML_VERBOSE" << std::endl; + stream << " printf(\"Targets: \");" << std::endl; + stream << " printStateNames(target_set);" << std::endl; + stream << "#endif" << std::endl; + stream << std::endl; + + stream << "// REMEMBER_HISTORY:" << std::endl; + stream << " for (int i = 0; i < SCXML_NUMBER_STATES; i++) {" << std::endl; + stream << " if unlikely(scxml_states[i].type == SCXML_STATE_HISTORY_SHALLOW || scxml_states[i].type == SCXML_STATE_HISTORY_DEEP) {" << std::endl; + stream << " // a history state whose parent is about to be exited" << std::endl; + stream << " if unlikely(IS_SET(scxml_states[i].source, exit_set)) {" << std::endl; + stream << " char history[" << _stateCharArraySize << "] = " << _stateCharArrayInit << ";" << std::endl; + stream << " bit_copy(history, scxml_states[i].completion, " << _stateCharArraySize << ");" << std::endl; + stream << std::endl; + stream << " // set those states who were enabled" << std::endl; + stream << " bit_and(history, ctx->config, " << _stateCharArraySize << ");" << std::endl; + stream << std::endl; + stream << " // clear current history with completion mask" << std::endl; + stream << " bit_and_not(ctx->history, scxml_states[i].completion, " << _stateCharArraySize << ");" << std::endl; + stream << std::endl; + stream << " // set history" << std::endl; + stream << " bit_or(ctx->history, history, " << _stateCharArraySize << ");" << std::endl; + stream << " }" << std::endl; + stream << " }" << std::endl; + stream << " }" << std::endl; + + stream << "#ifdef SCXML_VERBOSE" << std::endl; + stream << " printf(\"Exiting: \");" << std::endl; + stream << " printStateNames(exit_set);" << std::endl; + stream << "#endif" << std::endl; + stream << std::endl; + + stream << "#ifdef SCXML_VERBOSE" << std::endl; + stream << " printf(\"History: \");" << std::endl; + stream << " printStateNames(ctx->history);" << std::endl; + stream << "#endif" << std::endl; + stream << std::endl; + + stream << "// EXIT_STATES:" << std::endl; + stream << " for (int i = SCXML_NUMBER_STATES - 1; i >= 0; i--) {" << std::endl; + stream << " if (IS_SET(i, exit_set) && IS_SET(i, ctx->config)) {" << std::endl; + stream << " // call all on exit handlers" << std::endl; + stream << " if (scxml_states[i].on_exit != NULL) {" << std::endl; + stream << " if unlikely((err = scxml_states[i].on_exit(ctx, &scxml_states[i], event)) != SCXML_ERR_OK)" << std::endl; + stream << " return err;" << std::endl; + stream << " }" << std::endl; + stream << " CLEARBIT(i, ctx->config);" << std::endl; + stream << " }" << std::endl; + stream << " }" << std::endl; + stream << std::endl; + + stream << "COMPLETE_CONFIG:" << std::endl; + stream << " // calculate new entry set" << std::endl; + stream << " bit_copy(entry_set, target_set, " << _stateCharArraySize << ");" << std::endl; + stream << std::endl; + stream << " // iterate for ancestors" << std::endl; + stream << " for (int i = 0; i < SCXML_NUMBER_STATES; i++) {" << std::endl; + stream << " if (IS_SET(i, entry_set)) {" << std::endl; + stream << " bit_or(entry_set, scxml_states[i].ancestors, " << _stateCharArraySize << ");" << std::endl; + stream << " }" << std::endl; + stream << " }" << std::endl; + stream << std::endl; + + stream << "// ADD_DESCENDANTS:" << std::endl; + stream << " // iterate for descendants" << std::endl; + stream << " for (int i = 0; i < SCXML_NUMBER_STATES; i++) {" << std::endl; + stream << " if (IS_SET(i, entry_set)) {" << std::endl; + stream << " switch (scxml_states[i].type) {" << std::endl; + stream << " case SCXML_STATE_PARALLEL: {" << std::endl; + stream << " bit_or(entry_set, scxml_states[i].completion, " << _stateCharArraySize << ");" << std::endl; + stream << " break;" << std::endl; + stream << " }" << std::endl; + stream << " case SCXML_STATE_HISTORY_SHALLOW:" << std::endl; + stream << " case SCXML_STATE_HISTORY_DEEP: {" << std::endl; + stream << " char history_targets[" << _stateCharArraySize << "] = " << _stateCharArrayInit << ";" << std::endl; + stream << " if (!bit_has_and(scxml_states[i].completion, ctx->history, " << _stateCharArraySize << ")) {" << std::endl; + stream << " // nothing set for history, look for a default transition or enter parents completion" << std::endl; + stream << " for (int j = 0; j < SCXML_NUMBER_TRANSITIONS; j++) {" << std::endl; + stream << " if unlikely(scxml_transitions[j].source == i) {" << std::endl; + stream << " bit_or(entry_set, scxml_transitions[j].target, " << _stateCharArraySize << ");" << std::endl; + stream << " SET_BIT(j, trans_set);" << std::endl; + stream << " break;" << std::endl; + stream << " }" << std::endl; + stream << " }" << std::endl; + stream << " // TODO: enter parents default completion here" << std::endl; + stream << " } else {" << std::endl; + stream << " bit_copy(history_targets, scxml_states[i].completion, " << _stateCharArraySize << ");" << std::endl; + stream << " bit_and(history_targets, ctx->history, " << _stateCharArraySize << ");" << std::endl; + stream << " bit_or(entry_set, history_targets, " << _stateCharArraySize << ");" << std::endl; + stream << " }" << std::endl; + stream << " break;" << std::endl; + stream << " }" << std::endl; + stream << " case SCXML_STATE_INITIAL: {" << std::endl; + stream << " for (int j = 0; j < SCXML_NUMBER_TRANSITIONS; j++) {" << std::endl; + stream << " if (scxml_transitions[j].source == i) {" << std::endl; + stream << " SET_BIT(j, trans_set);" << std::endl; + stream << " CLEARBIT(i, entry_set);" << std::endl; + stream << " bit_or(entry_set, scxml_transitions[j].target, " << _stateCharArraySize << ");" << std::endl; + stream << " // one target may have been above, reestablish completion" << std::endl; + stream << " // goto ADD_DESCENDANTS; // initial will have to be first!" << std::endl; + stream << " }" << std::endl; + stream << " }" << std::endl; + stream << " break;" << std::endl; + stream << " }" << std::endl; + stream << " case SCXML_STATE_COMPOUND: { // we need to check whether one child is already in entry_set" << std::endl; + stream << " if (!bit_has_and(entry_set, scxml_states[i].children, " << _stateCharArraySize << ") &&" << std::endl; + stream << " !bit_has_and(ctx->config, scxml_states[i].children, " << _stateCharArraySize << "))" << std::endl; + stream << " {" << std::endl; + stream << " bit_or(entry_set, scxml_states[i].completion, " << _stateCharArraySize << ");" << std::endl; + stream << " }" << std::endl; + stream << " break;" << std::endl; + stream << " }" << std::endl; + stream << " }" << std::endl; + stream << " }" << std::endl; + stream << " }" << std::endl; + stream << std::endl; + + stream << "#ifdef SCXML_VERBOSE" << std::endl; + stream << " printf(\"Transitions: \");" << std::endl; + stream << " printBitsetIndices(trans_set, sizeof(char) * 8 * " << _transCharArraySize << ");" << std::endl; + stream << "#endif" << std::endl; + stream << std::endl; + + stream << "// TAKE_TRANSITIONS:" << std::endl; + stream << " for (int i = 0; i < SCXML_NUMBER_TRANSITIONS; i++) {" << std::endl; + stream << " if (IS_SET(i, trans_set) && (scxml_transitions[i].type & SCXML_TRANS_HISTORY) == 0) {" << std::endl; + stream << " // call executable content in transition" << std::endl; + stream << " if (scxml_transitions[i].on_transition != NULL) {" << std::endl; + stream << " if unlikely((err = scxml_transitions[i].on_transition(ctx," << std::endl; + stream << " &scxml_states[scxml_transitions[i].source]," << std::endl; + stream << " event)) != SCXML_ERR_OK)" << std::endl; + stream << " return err;" << std::endl; + stream << " }" << std::endl; + stream << " }" << std::endl; + stream << " }" << std::endl; + stream << std::endl; + + stream << "#ifdef SCXML_VERBOSE" << std::endl; + stream << " printf(\"Entering: \");" << std::endl; + stream << " printStateNames(entry_set);" << std::endl; + stream << "#endif" << std::endl; + stream << std::endl; + + stream << "// ENTER_STATES:" << std::endl; + stream << " for (int i = 0; i < SCXML_NUMBER_STATES; i++) {" << std::endl; + stream << " if (IS_SET(i, entry_set) && !IS_SET(i, ctx->config)) {" << std::endl; + stream << " // these are no proper states" << std::endl; + stream << " if unlikely(scxml_states[i].type == SCXML_STATE_HISTORY_DEEP ||" << std::endl; + stream << " scxml_states[i].type == SCXML_STATE_HISTORY_SHALLOW ||" << std::endl; + stream << " scxml_states[i].type == SCXML_STATE_INITIAL)" << std::endl; + stream << " continue;" << std::endl; + stream << std::endl; + + stream << " SET_BIT(i, ctx->config);" << std::endl; + stream << std::endl; + + stream << " // initialize data" << std::endl; + stream << " if (!IS_SET(i, ctx->initialized_data)) {" << std::endl; + stream << " if unlikely(scxml_states[i].data != NULL && ctx->exec_content_init != NULL) {" << std::endl; + stream << " ctx->exec_content_init(ctx, scxml_states[i].data);" << std::endl; + stream << " }" << std::endl; + stream << " SET_BIT(i, ctx->initialized_data);" << std::endl; + stream << " }" << std::endl; + stream << std::endl; + + stream << " if (scxml_states[i].on_entry != NULL) {" << std::endl; + stream << " if unlikely((err = scxml_states[i].on_entry(ctx, &scxml_states[i], event)) != SCXML_ERR_OK)" << std::endl; + stream << " return err;" << std::endl; + stream << " }" << std::endl; + stream << std::endl; + + stream << " // handle final states" << std::endl; + stream << " if unlikely(scxml_states[i].type == SCXML_STATE_FINAL) {" << std::endl; + stream << " if unlikely(scxml_states[i].ancestors[0] == 0x01) {" << std::endl; + stream << " ctx->flags |= SCXML_CTX_TOP_LEVEL_FINAL;" << std::endl; + stream << " } else {" << std::endl; + stream << " // raise done event" << std::endl; + stream << " size_t parent = 0;" << std::endl; + stream << " for (int j = SCXML_NUMBER_STATES - 1; j >= 0; j--) {" << std::endl; + stream << " // we could trade runtime for memory here by saving the parent index" << std::endl; + stream << " if unlikely(IS_SET(j, scxml_states[i].ancestors)) {" << std::endl; + stream << " parent = j;" << std::endl; + stream << " break;" << std::endl; + stream << " }" << std::endl; + stream << " }" << std::endl; + stream << " // is this raised for toplevel final as well?" << std::endl; + if (_hasDoneData) { + stream << " scxml_elem_donedata* donedata = &scxml_elem_donedatas[0];" << std::endl; + stream << " while(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, &scxml_states[parent], (ELEM_DONEDATA_IS_SET(donedata) ? donedata : NULL));" << std::endl; + } else { + stream << " ctx->raise_done_event(ctx, &scxml_states[parent], NULL);" << std::endl; + } + stream << " }" << std::endl; + 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 (int j = 0; j < SCXML_NUMBER_STATES; j++) {" << std::endl; + stream << " if unlikely(scxml_states[j].type == SCXML_STATE_PARALLEL) {" << std::endl; + stream << " char parallel_children[" << _stateCharArraySize << "] = " << _stateCharArrayInit << ";" << std::endl; + stream << " size_t parallel = j;" << std::endl; + stream << " for (int k = 0; k < SCXML_NUMBER_STATES; k++) {" << std::endl; + stream << " if unlikely(IS_SET(parallel, scxml_states[k].ancestors) && IS_SET(k, ctx->config)) {" << std::endl; + stream << " if (scxml_states[k].type == SCXML_STATE_FINAL) {" << std::endl; + stream << " bit_and_not(parallel_children, scxml_states[k].ancestors, " << _stateCharArraySize << ");" << std::endl; + stream << " } else {" << std::endl; + stream << " SET_BIT(k, parallel_children);" << std::endl; + stream << " }" << std::endl; + stream << " }" << std::endl; + stream << " }" << std::endl; + stream << " if unlikely(!bit_any_set(parallel_children, " << _stateCharArraySize << ")) {" << std::endl; + stream << " ctx->raise_done_event(ctx, &scxml_states[parallel], 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 << " }" << std::endl; + stream << std::endl; + + stream << "// HISTORY_TRANSITIONS:" << std::endl; + stream << " for (int i = 0; i < SCXML_NUMBER_TRANSITIONS; i++) {" << std::endl; + stream << " if unlikely(IS_SET(i, trans_set) && (scxml_transitions[i].type & SCXML_TRANS_HISTORY)) {" << std::endl; + stream << " // call executable content in transition" << std::endl; + stream << " if (scxml_transitions[i].on_transition != NULL) {" << std::endl; + stream << " if unlikely((err = scxml_transitions[i].on_transition(ctx," << std::endl; + stream << " &scxml_states[scxml_transitions[i].source]," << std::endl; + stream << " event)) != SCXML_ERR_OK)" << std::endl; + stream << " return err;" << std::endl; + stream << " }" << std::endl; + stream << " }" << std::endl; + stream << " }" << std::endl; + stream << std::endl; + + + stream << " return SCXML_ERR_OK;" << std::endl; + stream << "}" << std::endl; + stream << std::endl; } NodeSet<std::string> ChartToC::inPostFixOrder(const std::set<std::string>& elements, const Element<std::string>& root) { - NodeSet<std::string> nodes; - inPostFixOrder(elements, root, nodes); - return nodes; + NodeSet<std::string> nodes; + inPostFixOrder(elements, root, nodes); + return nodes; } void ChartToC::inPostFixOrder(const std::set<std::string>& elements, const Element<std::string>& root, NodeSet<std::string>& nodes) { - NodeList<std::string> children = root.getChildNodes(); - for (int i = 0; i < children.getLength(); i++) { - if (children.item(i).getNodeType() != Node_base::ELEMENT_NODE) - continue; - Arabica::DOM::Element<std::string> childElem(children.item(i)); - inPostFixOrder(elements, childElem, nodes); - - } - for (int i = 0; i < children.getLength(); i++) { - if (children.item(i).getNodeType() != Node_base::ELEMENT_NODE) - continue; - Arabica::DOM::Element<std::string> childElem(children.item(i)); - - if (elements.find(TAGNAME(childElem)) != elements.end()) { - nodes.push_back(childElem); - } - } + NodeList<std::string> children = root.getChildNodes(); + for (int i = 0; i < children.getLength(); i++) { + if (children.item(i).getNodeType() != Node_base::ELEMENT_NODE) + continue; + Arabica::DOM::Element<std::string> childElem(children.item(i)); + inPostFixOrder(elements, childElem, nodes); + + } + for (int i = 0; i < children.getLength(); i++) { + if (children.item(i).getNodeType() != Node_base::ELEMENT_NODE) + continue; + Arabica::DOM::Element<std::string> childElem(children.item(i)); + + if (elements.find(TAGNAME(childElem)) != elements.end()) { + nodes.push_back(childElem); + } + } } NodeSet<std::string> ChartToC::inDocumentOrder(const std::set<std::string>& elements, const Element<std::string>& root) { - NodeSet<std::string> nodes; - inDocumentOrder(elements, root, nodes); - return nodes; + NodeSet<std::string> nodes; + inDocumentOrder(elements, root, nodes); + return nodes; } void ChartToC::inDocumentOrder(const std::set<std::string>& elements, const Element<std::string>& root, NodeSet<std::string>& nodes) { - if (elements.find(TAGNAME(root)) != elements.end()) { - nodes.push_back(root); - } - - NodeList<std::string> children = root.getChildNodes(); - for (int i = 0; i < children.getLength(); i++) { - if (children.item(i).getNodeType() != Node_base::ELEMENT_NODE) - continue; - Arabica::DOM::Element<std::string> childElem(children.item(i)); - inDocumentOrder(elements, childElem, nodes); - } + if (elements.find(TAGNAME(root)) != elements.end()) { + nodes.push_back(root); + } + + NodeList<std::string> children = root.getChildNodes(); + for (int i = 0; i < children.getLength(); i++) { + if (children.item(i).getNodeType() != Node_base::ELEMENT_NODE) + continue; + Arabica::DOM::Element<std::string> childElem(children.item(i)); + inDocumentOrder(elements, childElem, nodes); + } } ChartToC::~ChartToC() { } - + }
\ No newline at end of file diff --git a/src/uscxml/transform/ChartToC.h b/src/uscxml/transform/ChartToC.h index 0ee0d3c..6e6bac0 100644 --- a/src/uscxml/transform/ChartToC.h +++ b/src/uscxml/transform/ChartToC.h @@ -34,57 +34,57 @@ namespace uscxml { class USCXML_API ChartToC : public InterpreterRC, public TransformerImpl { public: - - virtual ~ChartToC(); - static Transformer transform(const Interpreter& other); - - void writeTo(std::ostream& stream); - - static Arabica::XPath::NodeSet<std::string> inPostFixOrder(const std::set<std::string>& elements, - const Arabica::DOM::Element<std::string>& root); - static Arabica::XPath::NodeSet<std::string> inDocumentOrder(const std::set<std::string>& elements, - const Arabica::DOM::Element<std::string>& root); + + virtual ~ChartToC(); + static Transformer transform(const Interpreter& other); + + void writeTo(std::ostream& stream); + + static Arabica::XPath::NodeSet<std::string> inPostFixOrder(const std::set<std::string>& elements, + const Arabica::DOM::Element<std::string>& root); + static Arabica::XPath::NodeSet<std::string> inDocumentOrder(const std::set<std::string>& elements, + const Arabica::DOM::Element<std::string>& root); protected: - ChartToC(const Interpreter& other); - - static void inPostFixOrder(const std::set<std::string>& elements, - const Arabica::DOM::Element<std::string>& root, - Arabica::XPath::NodeSet<std::string>& nodes); - - static void inDocumentOrder(const std::set<std::string>& elements, - const Arabica::DOM::Element<std::string>& root, - Arabica::XPath::NodeSet<std::string>& nodes); - - void writeIncludes(std::ostream& stream); - void writeMacros(std::ostream& stream); - void writeTypes(std::ostream& stream); - void writeHelpers(std::ostream& stream); - void writeExecContent(std::ostream& stream); - void writeElementInfo(std::ostream& stream); - - void writeStates(std::ostream& stream); - void writeTransitions(std::ostream& stream); - void writeFSM(std::ostream& stream); - void writeCharArrayInitList(std::ostream& stream, const std::string& boolString); - - void writeExecContent(std::ostream& stream, const Arabica::DOM::Node<std::string>& node, int indent = 0); - - Arabica::XPath::NodeSet<std::string> computeExitSet(const Arabica::DOM::Element<std::string>& transition); - - Interpreter interpreter; - - Arabica::XPath::NodeSet<std::string> _states; - std::map<std::string, Arabica::DOM::Element<std::string> > _stateNames; - Arabica::XPath::NodeSet<std::string> _transitions; - - bool _hasGlobalScripts; - bool _hasDoneData; - - size_t _transCharArraySize; - std::string _transCharArrayInit; - - size_t _stateCharArraySize; - std::string _stateCharArrayInit; + ChartToC(const Interpreter& other); + + static void inPostFixOrder(const std::set<std::string>& elements, + const Arabica::DOM::Element<std::string>& root, + Arabica::XPath::NodeSet<std::string>& nodes); + + static void inDocumentOrder(const std::set<std::string>& elements, + const Arabica::DOM::Element<std::string>& root, + Arabica::XPath::NodeSet<std::string>& nodes); + + void writeIncludes(std::ostream& stream); + void writeMacros(std::ostream& stream); + void writeTypes(std::ostream& stream); + void writeHelpers(std::ostream& stream); + void writeExecContent(std::ostream& stream); + void writeElementInfo(std::ostream& stream); + + void writeStates(std::ostream& stream); + void writeTransitions(std::ostream& stream); + void writeFSM(std::ostream& stream); + void writeCharArrayInitList(std::ostream& stream, const std::string& boolString); + + void writeExecContent(std::ostream& stream, const Arabica::DOM::Node<std::string>& node, int indent = 0); + + Arabica::XPath::NodeSet<std::string> computeExitSet(const Arabica::DOM::Element<std::string>& transition); + + Interpreter interpreter; + + Arabica::XPath::NodeSet<std::string> _states; + std::map<std::string, Arabica::DOM::Element<std::string> > _stateNames; + Arabica::XPath::NodeSet<std::string> _transitions; + + bool _hasGlobalScripts; + bool _hasDoneData; + + size_t _transCharArraySize; + std::string _transCharArrayInit; + + size_t _stateCharArraySize; + std::string _stateCharArrayInit; }; } diff --git a/src/uscxml/transform/ChartToFSM.cpp b/src/uscxml/transform/ChartToFSM.cpp index d55ef24..b78a2dd 100644 --- a/src/uscxml/transform/ChartToFSM.cpp +++ b/src/uscxml/transform/ChartToFSM.cpp @@ -97,7 +97,7 @@ std::cerr << ")"; ChartToFSM::ChartToFSM(const Interpreter& other) { cloneFrom(other.getImpl()); - + _transitionsFromTree = true; _keepInvalidTransitions = false; _lastTimeStamp = tthread::chrono::system_clock::now(); @@ -116,20 +116,20 @@ ChartToFSM::ChartToFSM(const Interpreter& other) { if (envVarIEquals("USCXML_TRANSFORM_TRANS_FROM", "powerset")) _transitionsFromTree = false; - + _start = NULL; _currGlobalTransition = NULL; _transTree = NULL; - + _lastStateIndex = 0; _lastActiveIndex = 0; _lastTransIndex = 0; - + _maxEventSentChain = 0; _maxEventRaisedChain = 0; _doneEventRaiseTolerance = 0; _skipEventChainCalculations = false; - + addMonitor(this); } @@ -144,7 +144,7 @@ ChartToFSM::~ChartToFSM() { delete confIter->second; confIter++; } - + // tear down caches Arabica::XPath::NodeSet<std::string> allTransitions = filterChildElements(_nsInfo.xmlNSPrefix + "transition", _scxml, true); for (int i = 0; i < allTransitions.size(); i++) { @@ -180,7 +180,7 @@ InterpreterState ChartToFSM::interpret() { } std::map<size_t, size_t> histoGramm = Complexity::getTransitionHistogramm(_scxml); // abort(); - + uint64_t complexity = Complexity::stateMachineComplexity(this) + 1; std::cerr << "Approximate Complexity: " << complexity << std::endl; std::cerr << "Approximate Active Complexity: " << Complexity::stateMachineComplexity(this, Complexity::IGNORE_HISTORY | Complexity::IGNORE_NESTED_DATA) + 1 << std::endl; @@ -224,7 +224,7 @@ InterpreterState ChartToFSM::interpret() { for (int i = 0; i < histories.size(); i++) { _historyTargets[ATTR_CAST(histories[i], "id")] = Element<std::string>(histories[i]); } - + _binding = (HAS_ATTR(_scxml, "binding") && iequals(ATTR(_scxml, "binding"), "late") ? LATE : EARLY); _alreadyFlat = (HAS_ATTR(_scxml, "flat") && stringIsTrue(ATTR(_scxml, "flat"))); @@ -232,7 +232,7 @@ InterpreterState ChartToFSM::interpret() { reassembleFromFlat(); return _state; } - + // set invokeid for all invokers to parent state if none given NodeSet<std::string> invokers = filterChildElements(_nsInfo.xmlNSPrefix + "invoke", _scxml, true); for (int i = 0; i < invokers.size(); i++) { @@ -265,14 +265,14 @@ InterpreterState ChartToFSM::interpret() { _scxml.appendChild(initialElem); initialTransitions.push_back(transitionElem); } - + if (!_skipEventChainCalculations) annotateRaiseAndSend(_scxml); - + // std::cout << _scxml << std::endl; - + indexTransitions(); - + // add initial transitions as least prior for (int i = 0; i < initialTransitions.size() ; i++) { indexedTransitions.push_back(Element<std::string>(initialTransitions[i])); @@ -293,7 +293,7 @@ InterpreterState ChartToFSM::interpret() { // gather and set index attribute o states NodeSet<std::string> allStates = getAllStates(); allStates.to_document_order(); - + indexedStates.resize(allStates.size()); for (int i = 0; i < allStates.size(); i++) { Element<std::string> state = Element<std::string>(allStates[i]); @@ -309,9 +309,9 @@ InterpreterState ChartToFSM::interpret() { // std::cerr << _scxml << std::endl; - // create a _flatDoc for the FSM - DOMImplementation<std::string> domFactory = Arabica::SimpleDOM::DOMImplementation<std::string>::getDOMImplementation(); - _flatDoc = domFactory.createDocument(_document.getNamespaceURI(), "", 0); + // create a _flatDoc for the FSM + DOMImplementation<std::string> domFactory = Arabica::SimpleDOM::DOMImplementation<std::string>::getDOMImplementation(); + _flatDoc = domFactory.createDocument(_document.getNamespaceURI(), "", 0); GlobalTransition* globalTransition = new GlobalTransition(initialTransitions, _dataModel, this); globalTransition->index = _lastTransIndex++; @@ -323,7 +323,7 @@ InterpreterState ChartToFSM::interpret() { enterStates(initialTransitions); globalTransition->destination = FlatStateIdentifier::toStateId(_configuration); globalTransition->activeDestination = globalTransition->destination; - + explode(); DUMP_STATS(0, true); @@ -363,7 +363,7 @@ void ChartToFSM::executeContent(const Arabica::DOM::Element<std::string>& conten } } return; - + HAS_VALID_CHILDREN: if (false) { } else if (TAGNAME(content) == "transition") { @@ -379,21 +379,21 @@ HAS_VALID_CHILDREN: } if (!_skipEventChainCalculations && - (_maxEventRaisedChain != UNDECIDABLE || _maxEventSentChain != UNDECIDABLE)) { + (_maxEventRaisedChain != UNDECIDABLE || _maxEventSentChain != UNDECIDABLE)) { assert(content.hasAttribute("raise") && content.hasAttribute("send")); std::string raiseAttr = content.getAttribute("raise"); std::string sendAttr = content.getAttribute("send"); - + _currGlobalTransition->eventsRaised = (raiseAttr == "-1" ? UNDECIDABLE : _currGlobalTransition->eventsRaised + strTo<uint32_t>(raiseAttr)); _currGlobalTransition->eventsSent = (sendAttr == "-1" ? UNDECIDABLE : _currGlobalTransition->eventsSent + strTo<uint32_t>(sendAttr)); - + if (_currGlobalTransition->eventsRaised > _maxEventRaisedChain) _maxEventRaisedChain = _currGlobalTransition->eventsRaised; if (_currGlobalTransition->eventsSent > _maxEventSentChain) _maxEventSentChain = _currGlobalTransition->eventsSent; } - + _currGlobalTransition->actions.push_back(action); _currGlobalTransition->hasExecutableContent = true; } @@ -434,19 +434,19 @@ void ChartToFSM::internalDoneSend(const Arabica::DOM::Element<std::string>& stat onentry.appendChild(raise); - if (doneData) { - Arabica::XPath::NodeSet<std::string> contents = filterChildElements(_nsInfo.xmlNSPrefix + "content", doneData); - if (contents.size() > 0) { - Node<std::string> imported = _flatDoc.importNode(contents[0], true); - raise.appendChild(imported); - } - Arabica::XPath::NodeSet<std::string> params = filterChildElements(_nsInfo.xmlNSPrefix + "param", doneData); - if (params.size() > 0) { - Node<std::string> imported = _flatDoc.importNode(params[0], true); - raise.appendChild(imported); - } - } - + if (doneData) { + Arabica::XPath::NodeSet<std::string> contents = filterChildElements(_nsInfo.xmlNSPrefix + "content", doneData); + if (contents.size() > 0) { + Node<std::string> imported = _flatDoc.importNode(contents[0], true); + raise.appendChild(imported); + } + Arabica::XPath::NodeSet<std::string> params = filterChildElements(_nsInfo.xmlNSPrefix + "param", doneData); + if (params.size() > 0) { + Node<std::string> imported = _flatDoc.importNode(params[0], true); + raise.appendChild(imported); + } + } + raise.setAttribute("event", "done.state." + ATTR_CAST(state, "id")); // parent?! @@ -455,7 +455,7 @@ void ChartToFSM::internalDoneSend(const Arabica::DOM::Element<std::string>& stat _currGlobalTransition->actions.push_back(action); if (!_skipEventChainCalculations && - (_maxEventRaisedChain != UNDECIDABLE || _maxEventSentChain != UNDECIDABLE)) + (_maxEventRaisedChain != UNDECIDABLE || _maxEventSentChain != UNDECIDABLE)) _currGlobalTransition->eventsRaised++; _currGlobalTransition->hasExecutableContent = true; @@ -463,13 +463,13 @@ void ChartToFSM::internalDoneSend(const Arabica::DOM::Element<std::string>& stat static bool isSuperset(const GlobalTransition* t1, const GlobalTransition* t2) { bool isSuperset = true; - + if (t1->transitionRefs.size() >= t2->transitionRefs.size()) return false; - + NodeSet<std::string> t1Trans = t1->getTransitions(); NodeSet<std::string> t2Trans = t2->getTransitions(); - + for (int i = 0; i < t1Trans.size(); i++) { if (!InterpreterImpl::isMember(t1Trans[i], t2Trans)) { isSuperset = false; @@ -515,7 +515,7 @@ static bool filterSameHierarchy(const NodeSet<std::string>& transitions) { return true; } - + static bool filterChildEnabled(const NodeSet<std::string>& transitions) { // drop any transition that is already enabled by a child NodeSet<std::string> filteredTransitions; @@ -548,7 +548,7 @@ static bool filterChildEnabled(const NodeSet<std::string>& transitions) { bool ChartToFSM::hasForeachInBetween(const Arabica::DOM::Node<std::string>& ancestor, const Arabica::DOM::Node<std::string>& child) { if (!ancestor || !child) return false; - + Node<std::string> currChild = child; while(currChild != ancestor) { if (!currChild.getParentNode()) @@ -580,8 +580,8 @@ void ChartToFSM::annotateRaiseAndSend(const Arabica::DOM::Element<std::string>& } execContentElem.setAttribute("raise", toStr(nrRaise)); - DONE_COUNT_RAISE: - +DONE_COUNT_RAISE: + int nrSend = 0; NodeSet<std::string> sends = filterChildElements(_nsInfo.xmlNSPrefix + "send", execContent[i], true); for (int j = 0; j < sends.size(); j++) { @@ -594,151 +594,151 @@ void ChartToFSM::annotateRaiseAndSend(const Arabica::DOM::Element<std::string>& } execContentElem.setAttribute("send", toStr(nrSend)); - DONE_COUNT_SEND: +DONE_COUNT_SEND: ; } } void ChartToFSM::annotateDomain() { - Arabica::XPath::NodeSet<std::string> allTransitions = filterChildElements(_nsInfo.xmlNSPrefix + "transition", _scxml, true); - for (int i = 0; i < allTransitions.size(); i++) { - Element<std::string> transition(allTransitions[i]); - Arabica::DOM::Node<std::string> domain = getTransitionDomain(transition); - if (domain) { - transition.setAttribute("domain", (HAS_ATTR_CAST(domain, "id") ? ATTR_CAST(domain, "id") : DOMUtils::xPathForNode(domain))); - } else { - transition.setAttribute("domain", "#UNDEF"); - } - } + Arabica::XPath::NodeSet<std::string> allTransitions = filterChildElements(_nsInfo.xmlNSPrefix + "transition", _scxml, true); + for (int i = 0; i < allTransitions.size(); i++) { + Element<std::string> transition(allTransitions[i]); + Arabica::DOM::Node<std::string> domain = getTransitionDomain(transition); + if (domain) { + transition.setAttribute("domain", (HAS_ATTR_CAST(domain, "id") ? ATTR_CAST(domain, "id") : DOMUtils::xPathForNode(domain))); + } else { + transition.setAttribute("domain", "#UNDEF"); + } + } } - + void ChartToFSM::annotateExitSet() { - Arabica::XPath::NodeSet<std::string> allTransitions = filterChildElements(_nsInfo.xmlNSPrefix + "transition", _scxml, true); - for (int i = 0; i < allTransitions.size(); i++) { - Element<std::string> transition(allTransitions[i]); - Arabica::DOM::Node<std::string> domain = getTransitionDomain(transition); - - Arabica::XPath::NodeSet<std::string> allStates = getAllStates(); - std::ostringstream exitSetStr; - std::string seperator = ""; - for (int j = 0; j < allStates.size(); j++) { - Element<std::string> state(allStates[j]); - if (state.getParentNode() == domain) { - exitSetStr << seperator << (HAS_ATTR(state, "id") ? ATTR(state, "id") : DOMUtils::xPathForNode(state)); - seperator = ", "; - } - } - transition.setAttribute("exitset", exitSetStr.str()); - } + Arabica::XPath::NodeSet<std::string> allTransitions = filterChildElements(_nsInfo.xmlNSPrefix + "transition", _scxml, true); + for (int i = 0; i < allTransitions.size(); i++) { + Element<std::string> transition(allTransitions[i]); + Arabica::DOM::Node<std::string> domain = getTransitionDomain(transition); + + Arabica::XPath::NodeSet<std::string> allStates = getAllStates(); + std::ostringstream exitSetStr; + std::string seperator = ""; + for (int j = 0; j < allStates.size(); j++) { + Element<std::string> state(allStates[j]); + if (state.getParentNode() == domain) { + exitSetStr << seperator << (HAS_ATTR(state, "id") ? ATTR(state, "id") : DOMUtils::xPathForNode(state)); + seperator = ", "; + } + } + transition.setAttribute("exitset", exitSetStr.str()); + } } - + void ChartToFSM::annotateEntrySet() { - Arabica::XPath::NodeSet<std::string> allTransitions = filterChildElements(_nsInfo.xmlNSPrefix + "transition", _scxml, true); - for (int i = 0; i < allTransitions.size(); i++) { - Element<std::string> transition(allTransitions[i]); - - NodeSet<std::string> tmpTransitions; - NodeSet<std::string> tmpStatesToEnter; - NodeSet<std::string> tmpStatesForDefaultEntry; - std::map<std::string, Arabica::DOM::Node<std::string> > tmpDefaultHistoryContent; - - tmpTransitions.push_back(transition); - computeEntrySet(tmpTransitions, tmpStatesToEnter, tmpStatesForDefaultEntry, tmpDefaultHistoryContent); - - std::ostringstream entrySetStr; - std::string seperator = ""; - - for (int j = 0; j < tmpStatesToEnter.size(); j++) { - Element<std::string> state(tmpStatesToEnter[j]); - entrySetStr << seperator << (HAS_ATTR(state, "id") ? ATTR(state, "id") : DOMUtils::xPathForNode(state)); - seperator = ", "; - } - for (int j = 0; j < tmpStatesForDefaultEntry.size(); j++) { - Element<std::string> state(tmpStatesForDefaultEntry[j]); - entrySetStr << seperator << (HAS_ATTR(state, "id") ? ATTR(state, "id") : DOMUtils::xPathForNode(state)); - seperator = ", "; - } - transition.setAttribute("entryset", entrySetStr.str()); - - } + Arabica::XPath::NodeSet<std::string> allTransitions = filterChildElements(_nsInfo.xmlNSPrefix + "transition", _scxml, true); + for (int i = 0; i < allTransitions.size(); i++) { + Element<std::string> transition(allTransitions[i]); + + NodeSet<std::string> tmpTransitions; + NodeSet<std::string> tmpStatesToEnter; + NodeSet<std::string> tmpStatesForDefaultEntry; + std::map<std::string, Arabica::DOM::Node<std::string> > tmpDefaultHistoryContent; + + tmpTransitions.push_back(transition); + computeEntrySet(tmpTransitions, tmpStatesToEnter, tmpStatesForDefaultEntry, tmpDefaultHistoryContent); + + std::ostringstream entrySetStr; + std::string seperator = ""; + + for (int j = 0; j < tmpStatesToEnter.size(); j++) { + Element<std::string> state(tmpStatesToEnter[j]); + entrySetStr << seperator << (HAS_ATTR(state, "id") ? ATTR(state, "id") : DOMUtils::xPathForNode(state)); + seperator = ", "; + } + for (int j = 0; j < tmpStatesForDefaultEntry.size(); j++) { + Element<std::string> state(tmpStatesForDefaultEntry[j]); + entrySetStr << seperator << (HAS_ATTR(state, "id") ? ATTR(state, "id") : DOMUtils::xPathForNode(state)); + seperator = ", "; + } + transition.setAttribute("entryset", entrySetStr.str()); + + } } void ChartToFSM::annotateConflicts() { - Arabica::XPath::NodeSet<std::string> allTransitions = filterChildElements(_nsInfo.xmlNSPrefix + "transition", _scxml, true); - Arabica::XPath::NodeSet<std::string> allStates = getAllStates(); - - for (int i = 0; i < allTransitions.size(); i++) { - Element<std::string> t1(allTransitions[i]); - if (!isState(Element<std::string>(t1.getParentNode()))) - continue; - - Arabica::DOM::Node<std::string> d1 = getTransitionDomain(t1); - - Arabica::XPath::NodeSet<std::string> exitSet1; - for (int k = 0; k < allStates.size(); k++) { - Element<std::string> state(allStates[k]); - if (isDescendant(state, d1)) { - exitSet1.push_back(state); - } - } - - std::ostringstream preemptionStr; - std::string seperator = ""; - - for (int j = 0; j < allTransitions.size(); j++) { - if ( i == j) - continue; - - Element<std::string> t2(allTransitions[j]); - if (!isState(Element<std::string>(t2.getParentNode()))) - continue; - - Arabica::DOM::Node<std::string> d2 = getTransitionDomain(t2); - - Arabica::XPath::NodeSet<std::string> exitSet2; - for (int k = 0; k < allStates.size(); k++) { - Element<std::string> state(allStates[k]); - if (isDescendant(state, d2)) { - exitSet2.push_back(state); - } - } - - if (hasIntersection(exitSet1, exitSet2)) { - preemptionStr << seperator << (HAS_ATTR(t2, "priority") ? ATTR(t2, "priority") : DOMUtils::xPathForNode(t2)); - seperator = ", "; - } + Arabica::XPath::NodeSet<std::string> allTransitions = filterChildElements(_nsInfo.xmlNSPrefix + "transition", _scxml, true); + Arabica::XPath::NodeSet<std::string> allStates = getAllStates(); + + for (int i = 0; i < allTransitions.size(); i++) { + Element<std::string> t1(allTransitions[i]); + if (!isState(Element<std::string>(t1.getParentNode()))) + continue; + + Arabica::DOM::Node<std::string> d1 = getTransitionDomain(t1); + + Arabica::XPath::NodeSet<std::string> exitSet1; + for (int k = 0; k < allStates.size(); k++) { + Element<std::string> state(allStates[k]); + if (isDescendant(state, d1)) { + exitSet1.push_back(state); + } + } + + std::ostringstream preemptionStr; + std::string seperator = ""; + + for (int j = 0; j < allTransitions.size(); j++) { + if ( i == j) + continue; + + Element<std::string> t2(allTransitions[j]); + if (!isState(Element<std::string>(t2.getParentNode()))) + continue; + + Arabica::DOM::Node<std::string> d2 = getTransitionDomain(t2); + + Arabica::XPath::NodeSet<std::string> exitSet2; + for (int k = 0; k < allStates.size(); k++) { + Element<std::string> state(allStates[k]); + if (isDescendant(state, d2)) { + exitSet2.push_back(state); + } + } + + if (hasIntersection(exitSet1, exitSet2)) { + preemptionStr << seperator << (HAS_ATTR(t2, "priority") ? ATTR(t2, "priority") : DOMUtils::xPathForNode(t2)); + seperator = ", "; + } // if (isDescendant(d1, d2) || isDescendant(d2, d1) || d1 == d2) { // preemptionStr << seperator << ATTR(t2, "priority"); // seperator = ", "; // } - } - if (preemptionStr.str().size() > 0) - t1.setAttribute("conflicts", preemptionStr.str()); + } + if (preemptionStr.str().size() > 0) + t1.setAttribute("conflicts", preemptionStr.str()); - } + } } void ChartToFSM::indexTransitions() { - indexedTransitions.clear(); - indexTransitions(_scxml); - + indexedTransitions.clear(); + indexTransitions(_scxml); + #if 1 - size_t index = indexedTransitions.size() - 1; - for (std::vector<Arabica::DOM::Element<std::string> >::iterator transIter = indexedTransitions.begin(); transIter != indexedTransitions.end(); transIter++) { - transIter->setAttribute("priority", toStr(index)); - index--; - } + size_t index = indexedTransitions.size() - 1; + for (std::vector<Arabica::DOM::Element<std::string> >::iterator transIter = indexedTransitions.begin(); transIter != indexedTransitions.end(); transIter++) { + transIter->setAttribute("priority", toStr(index)); + index--; + } #else - size_t index = 0; - for (std::vector<Arabica::DOM::Element<std::string> >::iterator transIter = indexedTransitions.begin(); transIter != indexedTransitions.end(); transIter++) { - transIter->setAttribute("priority", toStr(index)); - index++; - } + size_t index = 0; + for (std::vector<Arabica::DOM::Element<std::string> >::iterator transIter = indexedTransitions.begin(); transIter != indexedTransitions.end(); transIter++) { + transIter->setAttribute("priority", toStr(index)); + index++; + } #endif - // reverse indices for most prior to be in front - //std::reverse(indexedTransitions.begin(), indexedTransitions.end()); + // reverse indices for most prior to be in front + //std::reverse(indexedTransitions.begin(), indexedTransitions.end()); } #if 0 @@ -757,30 +757,30 @@ void ChartToFSM::indexTransitions(const Arabica::DOM::Element<std::string>& root indexTransitions(stateElem); } } - + #else - + void ChartToFSM::indexTransitions(const Arabica::DOM::Element<std::string>& root) { - // Post-order traversal of transitions - Arabica::XPath::NodeSet<std::string> childStates = getChildStates(root); - for (int i = 0; i < childStates.size(); i++) { - Element<std::string> childElem(childStates[i]); - indexTransitions(childElem); - } - - Arabica::XPath::NodeSet<std::string> levelTransitions = filterChildElements(_nsInfo.xmlNSPrefix + "transition", root); - for (int i = 0; i < levelTransitions.size(); i++) { - // push into index starting with least prior - indexedTransitions.push_back(Element<std::string>(levelTransitions[i])); - } + // Post-order traversal of transitions + Arabica::XPath::NodeSet<std::string> childStates = getChildStates(root); + for (int i = 0; i < childStates.size(); i++) { + Element<std::string> childElem(childStates[i]); + indexTransitions(childElem); + } + + Arabica::XPath::NodeSet<std::string> levelTransitions = filterChildElements(_nsInfo.xmlNSPrefix + "transition", root); + for (int i = 0; i < levelTransitions.size(); i++) { + // push into index starting with least prior + indexedTransitions.push_back(Element<std::string>(levelTransitions[i])); + } } - + #endif bool GlobalTransition::operator< (const GlobalTransition& other) const { const std::vector<Arabica::DOM::Element<std::string> >& indexedTransitions = interpreter->indexedTransitions; NodeSet<std::string> transitions = getTransitions(); - + for (std::vector<Element<std::string> >::const_iterator transIter = indexedTransitions.begin(); transIter != indexedTransitions.end(); transIter++) { const Element<std::string>& refTrans = *transIter; NodeSet<std::string> otherTransitions = other.getTransitions(); @@ -807,10 +807,10 @@ bool hasUnconditionalSuperset(GlobalTransition* first, GlobalTransition* second) NodeSet<std::string> firstTransitions = first->getTransitions(); NodeSet<std::string> secondTransitions = second->getTransitions(); - + // if (first->condition.size() > 0) // return false; - + if (isSuperset(second, first)) { for (int i = 0; i < firstTransitions.size(); i++) { if (!InterpreterImpl::isMember(firstTransitions[i], secondTransitions)) { @@ -839,11 +839,11 @@ std::list<GlobalTransition*> redundantRemove(std::list<GlobalTransition*> list) #if 1 std::list<GlobalTransition*>::iterator outerIter; std::list<GlobalTransition*>::iterator innerIter; - + outerIter = list.begin(); while(outerIter != list.end()) { innerIter = outerIter; - + while(innerIter != list.end()) { if (innerIter == outerIter) { innerIter++; @@ -866,25 +866,25 @@ std::list<GlobalTransition*> redundantRemove(std::list<GlobalTransition*> list) } innerIter++; } - + outerIter++; } - + #else for (std::list<GlobalTransition*>::iterator outerIter = list.begin(); - outerIter != list.end(); - outerIter++) { + outerIter != list.end(); + outerIter++) { for (std::list<GlobalTransition*>::iterator innerIter = outerIter; - innerIter != list.end(); - innerIter++) { - + innerIter != list.end(); + innerIter++) { + if (innerIter == outerIter) continue; - + GlobalTransition* t1 = *outerIter; GlobalTransition* t2 = *innerIter; - + if (hasUnconditionalSuperset(t1, t2)) { innerIter = list.erase(innerIter); continue; @@ -906,20 +906,20 @@ std::list<GlobalTransition*> redundantMark(std::list<GlobalTransition*> list) { #if 1 std::list<GlobalTransition*>::iterator outerIter; std::list<GlobalTransition*>::iterator innerIter; - + outerIter = list.begin(); while(outerIter != list.end()) { innerIter = outerIter; - + while(innerIter != list.end()) { if (innerIter == outerIter) { innerIter++; continue; } - + GlobalTransition* t1 = *outerIter; GlobalTransition* t2 = *innerIter; - + if (!t1->isValid || !t2->isValid) { innerIter++; continue; @@ -947,28 +947,28 @@ std::list<GlobalTransition*> redundantMark(std::list<GlobalTransition*> list) { } innerIter++; } - + outerIter++; } - + #else for (std::list<GlobalTransition*>::iterator outerIter = list.begin(); - outerIter != list.end(); - outerIter++) { + outerIter != list.end(); + outerIter++) { for (std::list<GlobalTransition*>::iterator innerIter = outerIter; - innerIter != list.end(); - innerIter++) { - + innerIter != list.end(); + innerIter++) { + if (innerIter == outerIter) continue; - + GlobalTransition* t1 = *outerIter; GlobalTransition* t2 = *innerIter; - + if (!t1->isValid || !t2->isValid) continue; - + if (hasUnconditionalSuperset(t1, t2)) { t2->isValid = false; t2->invalidMsg = "Unconditional superset"; @@ -992,7 +992,7 @@ std::list<GlobalTransition*> redundantMark(std::list<GlobalTransition*> list) { return list; } - + void TransitionTreeNode::dump(int indent) { std::string padding; for (int i = 0; i + 1 < indent; i++) { @@ -1000,23 +1000,27 @@ void TransitionTreeNode::dump(int indent) { } if (indent > 0) padding += "|-"; - + std::string typeString; switch (type) { - case TYPE_NESTED: - typeString = "NESTED"; break; - case TYPE_PARALLEL: - typeString = "PARALLEL"; break; - case TYPE_TRANSITION: - typeString = "TRANSITION"; break; - case TYPE_UNDEFINED: - typeString = "UNDEFINED"; break; - break; - default: - break; + case TYPE_NESTED: + typeString = "NESTED"; + break; + case TYPE_PARALLEL: + typeString = "PARALLEL"; + break; + case TYPE_TRANSITION: + typeString = "TRANSITION"; + break; + case TYPE_UNDEFINED: + typeString = "UNDEFINED"; + break; + break; + default: + break; } - + if (transition) { std::cerr << padding << "t" << ATTR(transition, "index") << " " << typeString << ": "; // std::cerr << (prevTransition != NULL ? " (" + prevTransition->nodeId + ") <-" : ""); @@ -1028,7 +1032,7 @@ void TransitionTreeNode::dump(int indent) { // std::cerr << (firstTransition != NULL ? " -> " + firstTransition->nodeId : ""); std::cerr << std::endl; } - + for (std::list<TransitionTreeNode*>::iterator childIter = children.begin(); childIter != children.end(); childIter++) { (*childIter)->dump(indent + 1); } @@ -1047,27 +1051,27 @@ void ChartToFSM::getPotentialTransitionsForConfFromTree(const Arabica::XPath::No // recursion start std::set<TransitionTreeNode*> transLeafs; - for (int i = 0; i < conf.size(); i++) { - DUMP_STATS(conf.size(), false); - - Element<std::string> confElem(conf[i]); - assert(_stateToTransTreeNode.find(confElem) != _stateToTransTreeNode.end()); - TransitionTreeNode* node = _stateToTransTreeNode[confElem]; - if (node->firstState == NULL) { // a leaf - ignore intermediates - // ascend to the first parent with transitions but stop at parallel nodes - while(node != NULL && node->firstTransition == NULL) { - if (node->parent && node->parent->type == TransitionTreeNode::TYPE_PARALLEL) - break; - node = node->parent; - } - if (node != NULL) { - transLeafs.insert(node); - } else { - //std::cerr << ATTR(confElem, "id") << " does not cause transitions" << std::endl; - } + for (int i = 0; i < conf.size(); i++) { + DUMP_STATS(conf.size(), false); + + Element<std::string> confElem(conf[i]); + assert(_stateToTransTreeNode.find(confElem) != _stateToTransTreeNode.end()); + TransitionTreeNode* node = _stateToTransTreeNode[confElem]; + if (node->firstState == NULL) { // a leaf - ignore intermediates + // ascend to the first parent with transitions but stop at parallel nodes + while(node != NULL && node->firstTransition == NULL) { + if (node->parent && node->parent->type == TransitionTreeNode::TYPE_PARALLEL) + break; + node = node->parent; + } + if (node != NULL) { + transLeafs.insert(node); + } else { + //std::cerr << ATTR(confElem, "id") << " does not cause transitions" << std::endl; } } - + } + std::list<std::set<TransitionTreeNode*> > stack; stack.push_back(transLeafs); // push follow-up configurations onto stack @@ -1075,7 +1079,7 @@ void ChartToFSM::getPotentialTransitionsForConfFromTree(const Arabica::XPath::No // pop from front of stack std::set<TransitionTreeNode*> stateList = stack.front(); stack.pop_front(); - + DUMP_STATS(conf.size(), false); #if 0 @@ -1087,40 +1091,40 @@ void ChartToFSM::getPotentialTransitionsForConfFromTree(const Arabica::XPath::No } std::cerr << std::endl; #endif - + /* * TransNodes contains a set of lists of transitions. - * In the inner stack we build every possible combination + * In the inner stack we build every possible combination * of picking at-most one from each list. */ - + /* create global transitions for every n-tuple in current set of lists */ std::list<std::pair<std::set<TransitionTreeNode*>, std::set<TransitionTreeNode*> > > innerStack; innerStack.push_back(std::make_pair(std::set<TransitionTreeNode*>(), stateList)); - + while(innerStack.size() > 0) { // picking at-most one from each list std::set<TransitionTreeNode*> remainingStates = innerStack.front().second; std::set<TransitionTreeNode*> fixedTransitions = innerStack.front().first; innerStack.pop_front(); - + if (remainingStates.size() > 0) { // iterate for each first element fixed TransitionTreeNode* firstRemainingState = *remainingStates.begin(); remainingStates.erase(remainingStates.begin()); - + if (firstRemainingState->firstTransition == NULL) { // no transitions at this state - reenqueue with NULL selection from this innerStack.push_back(std::make_pair(fixedTransitions, remainingStates)); continue; } - + TransitionTreeNode* currTrans = firstRemainingState->firstTransition; - + // choose none from firstList innerStack.push_back(std::make_pair(fixedTransitions, remainingStates)); - + while(currTrans != NULL) { std::set<TransitionTreeNode*> fixedAndThis(fixedTransitions); fixedAndThis.insert(currTrans); @@ -1136,7 +1140,7 @@ void ChartToFSM::getPotentialTransitionsForConfFromTree(const Arabica::XPath::No _perfTransProcessed++; NodeSet<std::string> fixed; - + #if 0 seperator = ""; for (std::set<TransitionTreeNode*>::iterator itemIter = fixedTransitions.begin(); itemIter != fixedTransitions.end(); itemIter++) { @@ -1146,7 +1150,7 @@ void ChartToFSM::getPotentialTransitionsForConfFromTree(const Arabica::XPath::No } std::cerr << " ## "; #endif - + seperator = ""; for (std::set<TransitionTreeNode*>::iterator itemIter = fixedTransitions.begin(); itemIter != fixedTransitions.end(); itemIter++) { TransitionTreeNode* currItem = *itemIter; @@ -1165,7 +1169,7 @@ void ChartToFSM::getPotentialTransitionsForConfFromTree(const Arabica::XPath::No // std::cerr << " - PREEMPTS" << std::endl; continue; } - + GlobalTransition* transition = new GlobalTransition(fixed, _dataModel, this); transition->index = _lastTransIndex++; @@ -1176,7 +1180,7 @@ void ChartToFSM::getPotentialTransitionsForConfFromTree(const Arabica::XPath::No // std::cerr << " - INVALID" << std::endl; continue; } - + _perfTransUsed++; outMap[transition->transitionId] = transition; @@ -1184,31 +1188,31 @@ void ChartToFSM::getPotentialTransitionsForConfFromTree(const Arabica::XPath::No } } } - + // create new set of transition lists by moving to parent states for (std::set<TransitionTreeNode*>::iterator stateIter = stateList.begin(); stateIter != stateList.end(); stateIter++) { TransitionTreeNode* origState = *stateIter; TransitionTreeNode* currState = origState; TransitionTreeNode* parentState = currState->parent; - + /** * We ascend the current state via its parent and add the parent with transitions. - * However, we break if we reached the top or if we passed a parallel state for + * However, we break if we reached the top or if we passed a parallel state for * wich we are not the first child */ - + while(parentState != NULL) { if (parentState->type == TransitionTreeNode::TYPE_PARALLEL && parentState->firstState != currState) { // the first child of the parallel state will continue this transition - we made sure to keep them break; } - + if (parentState->firstTransition != NULL) { // std::cerr << "#### Adding new parent lists for " << origState->nodeId << std::endl; - + std::set<TransitionTreeNode*> newStateList; newStateList.insert(parentState); - + // add all other states that are not a child of the parent state for (std::set<TransitionTreeNode*>::iterator newlistIter = stateList.begin(); newlistIter != stateList.end(); newlistIter++) { TransitionTreeNode* otherState = *newlistIter; @@ -1234,7 +1238,7 @@ TransitionTreeNode* ChartToFSM::buildTransTree(const Arabica::DOM::Element<std:: TransitionTreeNode* stateNode = new TransitionTreeNode(); stateNode->nodeId = nodeId; stateNode->state = root; - + if (TAGNAME(root) == _nsInfo.xmlNSPrefix + "parallel") { stateNode->type = TransitionTreeNode::TYPE_PARALLEL; } else { @@ -1250,7 +1254,7 @@ TransitionTreeNode* ChartToFSM::buildTransTree(const Arabica::DOM::Element<std:: nested.to_document_order(); TransitionTreeNode* lastNode = NULL; - + for (int i = 0; i < nested.size(); i++) { Element<std::string> nestedElem(nested[i]); if (TAGNAME(nestedElem) == _nsInfo.xmlNSPrefix + "transition") { @@ -1259,20 +1263,20 @@ TransitionTreeNode* ChartToFSM::buildTransTree(const Arabica::DOM::Element<std:: transNode->parent = stateNode; transNode->nodeId = nodeId + "-" + toStr(i); transNode->type = TransitionTreeNode::TYPE_TRANSITION; - + if (stateNode->firstTransition == NULL) { stateNode->firstTransition = transNode; } stateNode->children.push_back(transNode); stateNode->lastTransition = transNode; - + if (lastNode != NULL) { lastNode->nextTransition = transNode; transNode->prevTransition = lastNode; } lastNode = transNode; - - + + } else { TransitionTreeNode* deeperNode = buildTransTree(nestedElem, nodeId + "-" + toStr(i)); if (stateNode->firstState == NULL) { @@ -1283,9 +1287,9 @@ TransitionTreeNode* ChartToFSM::buildTransTree(const Arabica::DOM::Element<std:: stateNode->children.push_back(deeperNode); } } - + _stateToTransTreeNode[root] = stateNode; - + return stateNode; } @@ -1301,42 +1305,42 @@ void ChartToFSM::getPotentialTransitionsForConfFromPowerSet(const Arabica::XPath } std::cerr << std::endl; } - + // if (true) { // outMap = _confToTransitions[""]; // } - + if (allTransitions.size() == 0) return; // no transitions - + int nrElements = allTransitions.size(); int k = 0; int* stack = (int*)malloc((nrElements + 1) * sizeof(int)); memset(stack, 0, (nrElements + 1) * sizeof(int)); - + /** * Powerset is too naive and takes too long! - * We have it up to 500k checks/sec and still 2**30 is + * We have it up to 500k checks/sec and still 2**30 is * 1G+ for 30minutes in a single state out of 50k+! */ - + while(1) { // create the power set of all potential transitions - this is expensive! // see: http://www.programminglogic.com/powerset-algorithm-in-c/ - + if (stack[k] < nrElements) { stack[k+1] = stack[k] + 1; k++; } - + else { stack[k-1]++; k--; } - + if (k==0) break; - + NodeSet<std::string> transitions; // std::cerr << globalState->stateId << " [" << nrElements << "]: " << std::endl; for (int i = 1; i <= k; i++) { @@ -1344,27 +1348,27 @@ void ChartToFSM::getPotentialTransitionsForConfFromPowerSet(const Arabica::XPath transitions.push_back(allTransitions[stack[i] - 1]); } // std::cerr << std::endl; - + // transitions.push_back(allTransitions[0]); // transitions.push_back(allTransitions[4]); // transitions.push_back(allTransitions[5]); // transitions.push_back(allTransitions[7]); - + bool dump = false; - + // if (k == 4 && stack[1] == 1 && stack[2] == 5 && stack[3] == 6 && stack[4] == 8) { // dump = true; // } - + if (dump) DUMP_TRANSSET("at start"); - + _perfTransTotal++; _perfTransProcessed++; - + DUMP_STATS(nrElements, false); - + GlobalTransition* transition = NULL; - + // reduce to conflict-free subset // transitions.to_document_order(); if (!_keepInvalidTransitions) { @@ -1372,18 +1376,18 @@ void ChartToFSM::getPotentialTransitionsForConfFromPowerSet(const Arabica::XPath if(!filterSameState(transitions)) continue; if (dump) DUMP_TRANSSET("after same state filtered"); - + // remove those transitions with a child transition // if(!filterChildEnabled(transitions)) if(!filterSameHierarchy(transitions)) continue; if (dump) DUMP_TRANSSET("after child enabled filtered"); - + transitions = removeConflictingTransitions(transitions); if (dump) DUMP_TRANSSET("after conflicting filtered"); // algorithm can never reduce to empty set assert(transitions.size() > 0); - + // create a GlobalTransition object from the set transition = new GlobalTransition(transitions, _dataModel, this); if (!transition->isValid) { @@ -1393,13 +1397,13 @@ void ChartToFSM::getPotentialTransitionsForConfFromPowerSet(const Arabica::XPath } } else { transition = new GlobalTransition(transitions, _dataModel, this); - + // remove transitions in the same state if(!filterSameState(transitions)) { transition->isValid = false; transition->invalidReason = GlobalTransition::SAME_SOURCE_STATE; transition->invalidMsg = "Same source state"; - + // } else if(!filterChildEnabled(transitions)) { } else if(!filterSameHierarchy(transitions)) { transition->isValid = false; @@ -1413,7 +1417,7 @@ void ChartToFSM::getPotentialTransitionsForConfFromPowerSet(const Arabica::XPath transition->invalidMsg = "Preempting members"; } } - + } // two combinations might have projected onto the same conflict-free set @@ -1425,7 +1429,7 @@ void ChartToFSM::getPotentialTransitionsForConfFromPowerSet(const Arabica::XPath transition->index = _lastTransIndex++; _perfTransUsed++; - + // remember this conflict-free set // std::cerr << "New conflict-free subset: " << transition->transitionId << ":" << transition->eventDesc << std::endl; outMap[transition->transitionId] = transition; @@ -1433,12 +1437,12 @@ void ChartToFSM::getPotentialTransitionsForConfFromPowerSet(const Arabica::XPath // _confToTransitions[""] = outMap; return; } - + void ChartToFSM::explode() { std::list<std::pair<GlobalTransition*, GlobalState*> > statesRemaining; statesRemaining.push_back(std::make_pair(_currGlobalTransition, new GlobalState(_configuration, _alreadyEntered, _historyValue, _nsInfo.xmlNSPrefix, this))); - + // add all invokers for initial transition for (unsigned int i = 0; i < _statesToInvoke.size(); i++) { NodeSet<std::string> invokes = filterChildElements(_nsInfo.xmlNSPrefix + "invoke", _statesToInvoke[i]); @@ -1451,7 +1455,7 @@ void ChartToFSM::explode() { /** We need this to be a recursion in order not to exhaust the stack */ - + // append new global states and pop from front while(statesRemaining.size() > 0) { _perfStackSize = statesRemaining.size(); @@ -1459,18 +1463,18 @@ void ChartToFSM::explode() { _perfStatesProcessed++; DUMP_STATS(0, false); - + GlobalState* globalState = statesRemaining.front().second; _currGlobalTransition = statesRemaining.front().first; statesRemaining.pop_front(); - + // used to be conditionalized, we will just assume assert(_currGlobalTransition); if (_globalConf.find(globalState->stateId) != _globalConf.end()) { if (_currGlobalTransition->isEventless && - !_skipEventChainCalculations && - (_maxEventRaisedChain != UNDECIDABLE || _maxEventSentChain != UNDECIDABLE)) { + !_skipEventChainCalculations && + (_maxEventRaisedChain != UNDECIDABLE || _maxEventSentChain != UNDECIDABLE)) { // we arrived via a spontaneaous transition, do we need to update? updateRaisedAndSendChains(_globalConf[globalState->stateId], _currGlobalTransition, std::set<GlobalTransition*>()); } @@ -1487,7 +1491,7 @@ void ChartToFSM::explode() { // remember as global configuration _globalConf[globalState->stateId] = globalState; _globalConf[globalState->stateId]->index = _lastStateIndex++; - + if(_globalConf[globalState->stateId]->isFinal) { if (_activeConf.find(globalState->activeId) == _activeConf.end()) { assert(globalState->activeIndex == -1); @@ -1522,11 +1526,11 @@ void ChartToFSM::explode() { // reduce and sort transition sets for(std::map<std::string, GlobalTransition*>::iterator transSetIter = transitionSets.begin(); - transSetIter != transitionSets.end(); - transSetIter++) { + transSetIter != transitionSets.end(); + transSetIter++) { globalState->sortedOutgoing.push_back(transSetIter->second); } - + globalState->sortedOutgoing.sort(PtrComp<GlobalTransition>); // globalState->sortedOutgoing.unique(hasUnconditionalSuperset); // globalState->sortedOutgoing.unique(hasEarlierUnconditionalMatch); @@ -1542,23 +1546,23 @@ void ChartToFSM::explode() { // globalState->sortedOutgoing = redundantRemove(globalState->sortedOutgoing); // // std::cout << globalState->sortedOutgoing.size() << std::endl; - + assert(_activeConf.find(globalState->activeId) == _activeConf.end()); assert(globalState->activeIndex == -1); globalState->activeIndex = _lastActiveIndex++; _activeConf[globalState->activeId] = globalState; } - + // take every transition set and append resulting new state for(std::list<GlobalTransition*>::iterator transIter = globalState->sortedOutgoing.begin(); - transIter != globalState->sortedOutgoing.end(); - transIter++) { - + transIter != globalState->sortedOutgoing.end(); + transIter++) { + GlobalTransition* incomingTrans = _currGlobalTransition; GlobalTransition* outgoingTrans = *transIter; - + outgoingTrans->source = globalState->stateId; - + if (_keepInvalidTransitions && !outgoingTrans->isValid) continue; @@ -1572,8 +1576,8 @@ void ChartToFSM::explode() { // if outgoing transition is spontaneous, add number of events to chain if (outgoingTrans->isEventless && - !_skipEventChainCalculations && - (_maxEventRaisedChain != UNDECIDABLE || _maxEventSentChain != UNDECIDABLE)) { + !_skipEventChainCalculations && + (_maxEventRaisedChain != UNDECIDABLE || _maxEventSentChain != UNDECIDABLE)) { outgoingTrans->eventsChainRaised = MIN(incomingTrans->eventsChainRaised + outgoingTrans->eventsRaised, UNDECIDABLE); outgoingTrans->eventsChainSent = MIN(incomingTrans->eventsChainSent + outgoingTrans->eventsSent, UNDECIDABLE); @@ -1585,7 +1589,7 @@ void ChartToFSM::explode() { } statesRemaining.push_back(std::make_pair(outgoingTrans, new GlobalState(_configuration, _alreadyEntered, _historyValue, _nsInfo.xmlNSPrefix, this))); - + // add all invokers for (unsigned int i = 0; i < _statesToInvoke.size(); i++) { NodeSet<std::string> invokes = filterChildElements(_nsInfo.xmlNSPrefix + "invoke", _statesToInvoke[i]); @@ -1610,13 +1614,13 @@ void ChartToFSM::explode() { void ChartToFSM::updateRaisedAndSendChains(GlobalState* state, GlobalTransition* source, std::set<GlobalTransition*> visited) { for (std::list<GlobalTransition*>::iterator transIter = state->sortedOutgoing.begin(); transIter != state->sortedOutgoing.end(); transIter++) { GlobalTransition* transition = *transIter; - + if (!transition->isEventless) continue; // we do not care for eventful transitions - + // source leads to spontaneous transition -> update event chains bool eventChainsNeedUpdated = false; - + if (visited.find(transition) != visited.end()) { // potential spontaneous transition cycle! if (transition->eventsChainRaised > 0) @@ -1625,32 +1629,32 @@ void ChartToFSM::updateRaisedAndSendChains(GlobalState* state, GlobalTransition* _maxEventSentChain = UNDECIDABLE; return; } - + // UNDECIDABLE means "undecidable / endless" - + // will source increase our event chain? if (transition->eventsChainRaised != UNDECIDABLE && - transition->eventsChainRaised < source->eventsChainRaised + transition->eventsRaised) { + transition->eventsChainRaised < source->eventsChainRaised + transition->eventsRaised) { // taking transition after source causes more events in chain transition->eventsChainRaised = MIN(source->eventsChainRaised + transition->eventsRaised, UNDECIDABLE); eventChainsNeedUpdated = true; } if (transition->eventsChainSent != UNDECIDABLE && - transition->eventsChainSent < source->eventsChainSent + transition->eventsSent) { + transition->eventsChainSent < source->eventsChainSent + transition->eventsSent) { // taking transition after source causes more events in chain transition->eventsChainSent = MIN(source->eventsChainSent + transition->eventsSent, UNDECIDABLE); eventChainsNeedUpdated = true; } if (eventChainsNeedUpdated && - transition->destination.length() > 0 && - _globalConf.find(transition->destination) != _globalConf.end()) { + transition->destination.length() > 0 && + _globalConf.find(transition->destination) != _globalConf.end()) { visited.insert(transition); // iterate all spontaneous transitions in destination and update event chains updateRaisedAndSendChains(_globalConf[transition->destination], transition, visited); } - + if (transition->eventsChainRaised > _maxEventRaisedChain) _maxEventRaisedChain = transition->eventsChainRaised; if (transition->eventsChainSent > _maxEventSentChain) @@ -1690,7 +1694,7 @@ Arabica::XPath::NodeSet<std::string> ChartToFSM::refsToTransitions(const std::se } return transitions; } - + void ChartToFSM::beforeMicroStep(Interpreter interpreter) { } void ChartToFSM::onStableConfiguration(Interpreter interpreter) { @@ -1732,7 +1736,7 @@ GlobalState::GlobalState(const Arabica::XPath::NodeSet<std::string>& activeState const Arabica::XPath::NodeSet<std::string>& alreadyEnteredStates_, // we need to remember for binding=late const std::map<std::string, Arabica::XPath::NodeSet<std::string> >& historyStates_, const std::string& xmlNSPrefix, - ChartToFSM* flattener) { + ChartToFSM* flattener) { interpreter = flattener; activeIndex = -1; @@ -1778,13 +1782,13 @@ GlobalTransition* GlobalTransition::copyWithoutExecContent(GlobalTransition* oth GlobalTransition::GlobalTransition(const Arabica::XPath::NodeSet<std::string>& transitionSet, DataModel dataModel, ChartToFSM* flattener) { interpreter = flattener; - + eventsRaised = 0; eventsSent = 0; eventsChainRaised = 0; eventsChainSent = 0; historyBase = NULL; - + for (int i = 0; i < transitionSet.size(); i++) { transitionRefs.insert(strTo<int>(ATTR_CAST(transitionSet[i], "index"))); } @@ -1800,7 +1804,7 @@ GlobalTransition::GlobalTransition(const Arabica::XPath::NodeSet<std::string>& t hasExecutableContent = false; isValid = true; isEventless = true; - + #if 0 std::cerr << "################" << std::endl; for (int i = 0; i < transitions.size(); i++) { @@ -1910,7 +1914,7 @@ GlobalTransition::GlobalTransition(const Arabica::XPath::NodeSet<std::string>& t if (HAS_ATTR(transElem, "cond")) { conditions.push_back(boost::trim_copy(ATTR(transElem, "cond"))); } - + std::list<std::string> targets = InterpreterImpl::tokenizeIdRefs(ATTR(transElem, "target")); std::list<std::string>::iterator targetIter = targets.begin(); while(targetIter != targets.end()) { @@ -1922,7 +1926,7 @@ GlobalTransition::GlobalTransition(const Arabica::XPath::NodeSet<std::string>& t } // std::cout << std::endl << std::endl; } - + seperator = ""; for (std::vector<Element<std::string> >::iterator transIter = interpreter->indexedTransitions.begin(); transIter != interpreter->indexedTransitions.end(); transIter++) { const Element<std::string>& refTrans = *transIter; @@ -1938,7 +1942,7 @@ GlobalTransition::GlobalTransition(const Arabica::XPath::NodeSet<std::string>& t } seperator = " "; } - + // if (members == " 4 6 7 ") // std::cout << "asdfadf"; @@ -1968,7 +1972,7 @@ std::map<std::string, Arabica::XPath::NodeSet<std::string> > GlobalState::getHis return historyValue; } - + Arabica::XPath::NodeSet<std::string> GlobalTransition::getTransitions() const { return interpreter->refsToTransitions(transitionRefs); } diff --git a/src/uscxml/transform/ChartToFSM.h b/src/uscxml/transform/ChartToFSM.h index f7e00c5..ab4aed4 100644 --- a/src/uscxml/transform/ChartToFSM.h +++ b/src/uscxml/transform/ChartToFSM.h @@ -43,12 +43,12 @@ public: const Arabica::XPath::NodeSet<std::string>& alreadyEnteredStates, // we need to remember for binding=late const std::map<std::string, Arabica::XPath::NodeSet<std::string> >& historyStates, const std::string& xmlNSPrefix, - ChartToFSM* flattener); + ChartToFSM* flattener); std::set<int> activeStatesRefs; std::set<int> alreadyEnteredStatesRefs; std::map<std::string, std::set<int> > historyStatesRefs; - + std::list<GlobalTransition*> sortedOutgoing; std::string stateId; std::string activeId; @@ -56,9 +56,9 @@ public: unsigned long activeIndex; unsigned long index; bool isFinal; - + ChartToFSM* interpreter; - + Arabica::XPath::NodeSet<std::string> getActiveStates(); Arabica::XPath::NodeSet<std::string> getAlreadyEnteredStates(); std::map<std::string, Arabica::XPath::NodeSet<std::string> > getHistoryStates(); @@ -98,7 +98,7 @@ public: return true; if ((uninvoke && !other.uninvoke) || (!uninvoke && other.uninvoke)) return true; - + if (onEntry < other.onEntry) return onEntry < other.onEntry; if (raiseDone < other.raiseDone) @@ -124,11 +124,11 @@ public: bool operator!=(const Action& other) const { return !operator==(other); } - + friend USCXML_API std::ostream& operator<< (std::ostream& os, const Action& action); typedef std::list<GlobalTransition::Action>::iterator iter_t; - + Arabica::DOM::Element<std::string> onEntry; Arabica::DOM::Element<std::string> onExit; Arabica::DOM::Element<std::string> transition; @@ -137,12 +137,12 @@ public: Arabica::DOM::Element<std::string> invoke; Arabica::DOM::Element<std::string> uninvoke; Arabica::DOM::Element<std::string> raiseDone; - + }; GlobalTransition(const Arabica::XPath::NodeSet<std::string>& transitions, DataModel dataModel, ChartToFSM* flattener); static GlobalTransition* copyWithoutExecContent(GlobalTransition* other); - + bool isValid; // constructor will determine, calling code will delete if not std::string invalidMsg; InvalidReason invalidReason; @@ -151,17 +151,17 @@ public: bool isTargetless; // whether or not all our transitions are eventless bool isSubset; // there is a superset to this set bool hasExecutableContent; - + uint32_t eventsRaised; // internal events this transition will raise uint32_t eventsSent; // external events this transition will send uint32_t eventsChainRaised; // maximum number of internal events raised when taking this transition in a chain uint32_t eventsChainSent; // maximum number of external events raised when taking this transition in a chain - + std::set<int> startTransitionRefs; // indices of eventful transitions that might trigger this transition - + std::set<int> transitionRefs; // indizes of constituting transitions Arabica::XPath::NodeSet<std::string> getTransitions() const; - + std::list<std::string> eventNames; // the list of longest event names that will enable this set std::string eventDesc; // space-seperated eventnames for convenience std::string condition; // conjunction of all the set's conditions @@ -198,15 +198,15 @@ public: TYPE_NESTED, TYPE_TRANSITION }; - + TransitionTreeNode() - : prevTransition(NULL), - nextTransition(NULL), - firstTransition(NULL), - firstState(NULL), - parent(NULL), - type(TYPE_UNDEFINED) {} - + : prevTransition(NULL), + nextTransition(NULL), + firstTransition(NULL), + firstState(NULL), + parent(NULL), + type(TYPE_UNDEFINED) {} + virtual ~TransitionTreeNode() { for (std::list<TransitionTreeNode*>::iterator childIter = children.begin(); childIter != children.end(); childIter++) { delete(*childIter); @@ -229,7 +229,7 @@ public: std::string nodeId; TransitionTreeNodeType type; - + bool operator<(const TransitionTreeNode& other) const { return nodeId < other.nodeId; } @@ -242,16 +242,16 @@ public: virtual ~ChartToFSM(); void indexTransitions(); - void annotateDomain(); - void annotateExitSet(); - void annotateEntrySet(); - void annotateConflicts(); + void annotateDomain(); + void annotateExitSet(); + void annotateEntrySet(); + void annotateConflicts(); Arabica::DOM::Document<std::string> getDocument() const; // overwrite to return flat FSM protected: InterpreterState interpret(); - + GlobalState* _start; Arabica::DOM::Document<std::string> _flatDoc; std::map<std::string, GlobalState*> _globalConf; @@ -270,7 +270,7 @@ protected: private: Arabica::XPath::NodeSet<std::string> refsToStates(const std::set<int>&); Arabica::XPath::NodeSet<std::string> refsToTransitions(const std::set<int>&); - + // gather executable content per microstep void executeContent(const Arabica::DOM::Element<std::string>& content, bool rethrow = false); @@ -301,12 +301,12 @@ private: void updateRaisedAndSendChains(GlobalState* state, GlobalTransition* source, std::set<GlobalTransition*> visited); void reassembleFromFlat(); - + std::list<GlobalTransition*> sortTransitions(std::list<GlobalTransition*> list); // we need this static as we use it in a sort function static std::map<Arabica::DOM::Node<std::string>, Arabica::DOM::Node<std::string> > _transParents; - + static bool filterSameState(const Arabica::XPath::NodeSet<std::string>& transitions); uint64_t _perfTransProcessed; @@ -334,13 +334,13 @@ private: size_t _maxEventSentChain; size_t _maxEventRaisedChain; size_t _doneEventRaiseTolerance; - + GlobalTransition* _currGlobalTransition; std::map<std::string, std::map<std::string, GlobalTransition*> > _confToTransitions; - + TransitionTreeNode* _transTree; std::map<Arabica::DOM::Element<std::string>, TransitionTreeNode*> _stateToTransTreeNode; - + friend class GlobalTransition; friend class GlobalState; }; diff --git a/src/uscxml/transform/ChartToFlatSCXML.cpp b/src/uscxml/transform/ChartToFlatSCXML.cpp index c554218..2905444 100644 --- a/src/uscxml/transform/ChartToFlatSCXML.cpp +++ b/src/uscxml/transform/ChartToFlatSCXML.cpp @@ -52,7 +52,7 @@ ChartToFlatSCXML::operator Interpreter() { return Interpreter::fromClone(shared_from_this()); } - + Transformer ChartToFlatSCXML::transform(const Interpreter& other) { return boost::shared_ptr<TransformerImpl>(new ChartToFlatSCXML(other)); } @@ -79,10 +79,10 @@ void ChartToFlatSCXML::writeTo(std::ostream& stream) { if (HAS_ATTR(element, "final-target")) element.removeAttribute("final-target"); } - + if (envVarIsTrue("USCXML_FLAT_FSM_METRICS_ONLY")) return; - + stream << _scxml; } @@ -90,7 +90,7 @@ void ChartToFlatSCXML::createDocument() { if (HAS_ATTR(_scxml, "flat") && stringIsTrue(ATTR(_scxml, "flat"))) return; - + { NodeSet<std::string> allElements = filterChildType(Node_base::ELEMENT_NODE, _scxml, true); size_t nrElements = 0; @@ -100,36 +100,36 @@ void ChartToFlatSCXML::createDocument() { } std::cerr << "Number of elements before flattening: " << nrElements + 1 << std::endl; } - + if (_start == NULL) interpret(); // only if not already flat! - + if (envVarIsTrue("USCXML_FLAT_FSM_METRICS_ONLY")) return; - + Element<std::string> _origSCXML = _scxml; - + _scxml = _flatDoc.createElementNS(_nsInfo.nsURL, "scxml"); _nsInfo.setPrefix(_scxml); - + _scxml.setAttribute("flat", "true"); _flatDoc.appendChild(_scxml); - + if (HAS_ATTR(_origSCXML, "datamodel")) { _scxml.setAttribute("datamodel", ATTR(_origSCXML, "datamodel")); } - + if (HAS_ATTR(_origSCXML, "name")) { _scxml.setAttribute("name", ATTR(_origSCXML, "name")); } - + if (HAS_ATTR(_origSCXML, "binding")) { _scxml.setAttribute("binding", ATTR(_origSCXML, "binding")); } - + _scxml.setAttribute("initial", _start->stateId); - + NodeSet<std::string> datas; if (_binding == InterpreterImpl::LATE) { // with late binding, just copy direct datamodel childs @@ -144,34 +144,34 @@ void ChartToFlatSCXML::createDocument() { Node<std::string> imported = _flatDoc.importNode(datas[i], true); _scxml.appendChild(imported); } - - + + NodeSet<std::string> scripts = filterChildElements(_nsInfo.xmlNSPrefix + "script", _origSCXML); for (int i = 0; i < scripts.size(); i++) { Node<std::string> imported = _flatDoc.importNode(scripts[i], true); _scxml.appendChild(imported); } - + NodeSet<std::string> comments = filterChildType(Node_base::COMMENT_NODE, _origSCXML); for (int i = 0; i < comments.size(); i++) { Node<std::string> imported = _flatDoc.importNode(comments[i], true); _scxml.appendChild(imported); } - + std::vector<std::pair<std::string,GlobalState*> > sortedStates; sortedStates.insert(sortedStates.begin(), _globalConf.begin(), _globalConf.end()); std::sort(sortedStates.begin(), sortedStates.end(), sortStatesByIndex); - + // int index = 0; // for (std::vector<Element<std::string> >::iterator transIter = indexedTransitions.begin(); transIter != indexedTransitions.end(); transIter++) { // const Element<std::string>& refTrans = *transIter; // std::cerr << index++ << ": " << refTrans << std::endl; // } // std::cerr << std::endl; - + for (std::vector<std::pair<std::string,GlobalState*> >::iterator confIter = sortedStates.begin(); - confIter != sortedStates.end(); - confIter++) { + confIter != sortedStates.end(); + confIter++) { appendGlobalStateNode(confIter->second); } @@ -181,7 +181,7 @@ void ChartToFlatSCXML::createDocument() { if (scxmls.size() > 0) { _scxml = Element<std::string>(scxmls[0]); } - + { NodeSet<std::string> allElements = filterChildType(Node_base::ELEMENT_NODE, _scxml, true); size_t nrElements = 0; @@ -191,29 +191,29 @@ void ChartToFlatSCXML::createDocument() { } std::cerr << "Number of elements after flattening: " << nrElements + 1 << std::endl; } - + } void ChartToFlatSCXML::appendGlobalStateNode(GlobalState* globalState) { Element<std::string> state = _flatDoc.createElementNS(_nsInfo.nsURL, "state"); _nsInfo.setPrefix(state); - + state.setAttribute("step", toStr(globalState->index)); state.setAttribute("id", globalState->stateId); - + if (globalState->isFinal) state.setAttribute("final", "true"); - + std::list<GlobalTransition*>& transitionList = globalState->sortedOutgoing; - + // apend here, for transient state chains to trail the state _scxml.appendChild(state); - + size_t index = 0; for (std::list<GlobalTransition*>::iterator outIter = transitionList.begin(); - outIter != transitionList.end(); - outIter++) { + outIter != transitionList.end(); + outIter++) { // (*outIter)->index = globalState->index + ":" + toStr(index); state.appendChild(globalTransitionToNode(*outIter)); index++; @@ -226,48 +226,48 @@ void ChartToFlatSCXML::appendGlobalStateNode(GlobalState* globalState) { Node<std::string> ChartToFlatSCXML::globalTransitionToNode(GlobalTransition* globalTransition) { Element<std::string> transition = _flatDoc.createElementNS(_nsInfo.nsURL, "transition"); _nsInfo.setPrefix(transition); - + // transition.setAttribute("ref", globalTransition->index); - + #if 1 transition.setAttribute("members", globalTransition->members); #endif // transition.setAttribute("priority", toStr(globalTransition->priority)); - + if (!globalTransition->isEventless) { transition.setAttribute("event", globalTransition->eventDesc); } - + if (globalTransition->condition.size() > 0) { transition.setAttribute("cond", globalTransition->condition); } - + if (globalTransition->destination.size() > 0) { transition.setAttribute("final-target", globalTransition->destination); } - + NodeSet<std::string> transientStateChain; - + // current active state set FlatStateIdentifier flatId(globalTransition->source); std::list<std::string> currActiveStates = flatId.getActive(); - + // std::cerr << "From " << globalTransition->source << " to " << globalTransition->destination << ":" << std::endl; - + // gather content for new transient state NodeSet<std::string> childs; - + // aggregated entering / exiting to avoid states without childs while still labeling std::list<Arabica::DOM::Comment<std::string> > pendingComments; - + // iterate all actions taken during the transition for (std::list<GlobalTransition::Action>::iterator actionIter = globalTransition->actions.begin(); - actionIter != globalTransition->actions.end(); - actionIter++) { - + actionIter != globalTransition->actions.end(); + actionIter++) { + if (actionIter->transition) { // DETAIL_EXEC_CONTENT(transition, actionIter); - + Element<std::string> onexit = _flatDoc.createElementNS(_nsInfo.nsURL, "onexit"); _nsInfo.setPrefix(onexit); Node<std::string> child = actionIter->transition.getFirstChild(); @@ -286,7 +286,7 @@ Node<std::string> ChartToFlatSCXML::globalTransitionToNode(GlobalTransition* glo if (HAS_ATTR(actionIter->transition, "target")) commentSS << " to target '" << ATTR(actionIter->transition, "target") << "'"; commentSS << " "; - + if (onexit.hasChildNodes()) { if (envVarIsTrue("USCXML_ANNOTATE_VERBOSE_COMMENTS")) childs.push_back(_flatDoc.createComment(commentSS.str())); @@ -295,16 +295,16 @@ Node<std::string> ChartToFlatSCXML::globalTransitionToNode(GlobalTransition* glo if (envVarIsTrue("USCXML_ANNOTATE_VERBOSE_COMMENTS")) pendingComments.push_back(_flatDoc.createComment(commentSS.str())); } - + continue; } - + if (actionIter->onExit) { // DETAIL_EXEC_CONTENT(onExit, actionIter); childs.push_back(actionIter->onExit); continue; } - + if (actionIter->onEntry) { // DETAIL_EXEC_CONTENT(onEntry, actionIter); childs.push_back(actionIter->onEntry); @@ -324,12 +324,12 @@ Node<std::string> ChartToFlatSCXML::globalTransitionToNode(GlobalTransition* glo childs.push_back(invokeElem); continue; } - + if (actionIter->uninvoke) { // DETAIL_EXEC_CONTENT(uninvoke, actionIter); Element<std::string> uninvokeElem = _flatDoc.createElementNS(_nsInfo.nsURL, "uninvoke"); _nsInfo.setPrefix(uninvokeElem); - + if (HAS_ATTR(actionIter->uninvoke, "type")) { uninvokeElem.setAttribute("type", ATTR(actionIter->uninvoke, "type")); } @@ -345,7 +345,7 @@ Node<std::string> ChartToFlatSCXML::globalTransitionToNode(GlobalTransition* glo childs.push_back(uninvokeElem); continue; } - + if (actionIter->exited) { currActiveStates.remove(ATTR_CAST(actionIter->exited, "id")); if (childs.size() > 0) { @@ -358,7 +358,7 @@ Node<std::string> ChartToFlatSCXML::globalTransitionToNode(GlobalTransition* glo pendingComments.push_back(_flatDoc.createComment(" Exiting " + ATTR_CAST(actionIter->exited, "id") + " ")); } } - + if (actionIter->entered) { if (childs.size() > 0) { if (envVarIsTrue("USCXML_ANNOTATE_VERBOSE_COMMENTS")) @@ -369,7 +369,7 @@ Node<std::string> ChartToFlatSCXML::globalTransitionToNode(GlobalTransition* glo pendingComments.push_back(_flatDoc.createComment(" Entering " + ATTR_CAST(actionIter->entered, "id") + " ")); } currActiveStates.push_back(ATTR_CAST(actionIter->entered, "id")); - + // we entered a new child - check if it has a datamodel and we entered for the first time if (_binding == InterpreterImpl::LATE) { NodeSet<std::string> datamodel = filterChildElements(_nsInfo.xmlNSPrefix + "datamodel", actionIter->entered); @@ -379,35 +379,35 @@ Node<std::string> ChartToFlatSCXML::globalTransitionToNode(GlobalTransition* glo } } } - + CREATE_TRANSIENT_STATE_WITH_CHILDS(FlatStateIdentifier::toStateId(currActiveStates)) - + if (transientStateChain.size() > 0) { Element<std::string> prevExitTransitionElem; - + for (int i = 0; i < transientStateChain.size(); i++) { Element<std::string> transientStateElem = Element<std::string>(transientStateChain[i]); transientStateElem.setAttribute("id", transientStateElem.getAttribute("id") + "-via-" + toStr(_lastTransientStateId++)); - + Element<std::string> exitTransition = _flatDoc.createElementNS(_nsInfo.nsURL, "transition"); _nsInfo.setPrefix(exitTransition); - + if (prevExitTransitionElem) { // point previous to this one prevExitTransitionElem.setAttribute("target", transientStateElem.getAttribute("id")); } else { // update globalTransition->source target } - + transientStateElem.appendChild(exitTransition); prevExitTransitionElem = exitTransition; - + if (i == 0) transition.setAttribute("target", transientStateElem.getAttribute("id")); - + _scxml.appendChild(transientStateElem); } - + // last one points to actual target assert(prevExitTransitionElem); prevExitTransitionElem.setAttribute("target", globalTransition->destination); @@ -415,11 +415,11 @@ Node<std::string> ChartToFlatSCXML::globalTransitionToNode(GlobalTransition* glo } else if (transientStateChain.size() == 1) { Element<std::string> transientStateElem = Element<std::string>(transientStateChain[0]); transientStateElem.setAttribute("onlyOne", "yes!"); - + Element<std::string> exitTransition = _flatDoc.createElementNS(_nsInfo.nsURL, "transition"); _nsInfo.setPrefix(exitTransition); exitTransition.setAttribute("target", globalTransition->destination); - + transientStateElem.appendChild(exitTransition); _scxml.appendChild(transientStateElem); @@ -428,7 +428,7 @@ Node<std::string> ChartToFlatSCXML::globalTransitionToNode(GlobalTransition* glo } else { transition.setAttribute("target", globalTransition->destination); } - + assert(HAS_ATTR_CAST(transition, "target")); return transition; } diff --git a/src/uscxml/transform/ChartToFlatSCXML.h b/src/uscxml/transform/ChartToFlatSCXML.h index 7afe3c5..a278721 100644 --- a/src/uscxml/transform/ChartToFlatSCXML.h +++ b/src/uscxml/transform/ChartToFlatSCXML.h @@ -33,17 +33,17 @@ public: operator Interpreter(); Arabica::DOM::Document<std::string> getDocument() const { - if (_flatDoc) - return _flatDoc; - return _document; + if (_flatDoc) + return _flatDoc; + return _document; } protected: void writeTo(std::ostream& stream); - + ChartToFlatSCXML(const Interpreter& other) : TransformerImpl(), ChartToFSM(other), _lastTransientStateId(0) {} void createDocument(); - + void appendGlobalStateNode(GlobalState* globalState); Arabica::DOM::Node<std::string> globalTransitionToNode(GlobalTransition* globalTransition); static bool sortStatesByIndex(const std::pair<std::string,GlobalState*>& s1, const std::pair<std::string,GlobalState*>& s2); diff --git a/src/uscxml/transform/ChartToMinimalSCXML.cpp b/src/uscxml/transform/ChartToMinimalSCXML.cpp index ecfa12b..69ac9cb 100644 --- a/src/uscxml/transform/ChartToMinimalSCXML.cpp +++ b/src/uscxml/transform/ChartToMinimalSCXML.cpp @@ -38,7 +38,7 @@ Transformer ChartToMinimalSCXML::transform(const Interpreter& other) { ChartToMinimalSCXML::ChartToMinimalSCXML(const Interpreter& other) : TransformerImpl(), _retainAsComments(false), _step(1) { cloneFrom(other.getImpl()); - + // a bit messy but needed for SCXML IO Processor with session id target _selfPtr = boost::shared_ptr<InterpreterImpl>(this, Deleter()); Interpreter::addInstance(_selfPtr); @@ -47,7 +47,7 @@ ChartToMinimalSCXML::ChartToMinimalSCXML(const Interpreter& other) : Transformer void ChartToMinimalSCXML::writeTo(std::ostream& stream) { addMonitor(this); - + { NodeSet<std::string> allElements = filterChildType(Node_base::ELEMENT_NODE, _scxml, true); size_t nrElements = 0; @@ -57,7 +57,7 @@ void ChartToMinimalSCXML::writeTo(std::ostream& stream) { } std::cerr << "Number of elements before reduction: " << nrElements + 1 << std::endl; } - + // test 278 - move embedded datas to topmost datamodel if (_binding == EARLY) { // move all data elements into topmost datamodel element @@ -75,7 +75,7 @@ void ChartToMinimalSCXML::writeTo(std::ostream& stream) { while(topMostDatamodel.hasChildNodes()) topMostDatamodel.removeChild(topMostDatamodel.getFirstChild()); - + for (int i = 0; i < datas.size(); i++) { if (!isInEmbeddedDocument(datas[i])) { topMostDatamodel.appendChild(datas[i]); @@ -83,10 +83,10 @@ void ChartToMinimalSCXML::writeTo(std::ostream& stream) { } } } - + char* waitForEnv = getenv("USCXML_MINIMIZE_WAIT_MS"); _retainAsComments = envVarIsTrue("USCXML_MINIMIZE_RETAIN_AS_COMMENTS"); - + long waitFor = -1; if (waitForEnv != NULL) { @@ -114,7 +114,7 @@ void ChartToMinimalSCXML::writeTo(std::ostream& stream) { } } stop(); - + removeUnvisited(_scxml); { @@ -140,11 +140,11 @@ void ChartToMinimalSCXML::removeUnvisited(Arabica::DOM::Node<std::string>& node) Element<std::string> elem(node); if (isInEmbeddedDocument(elem) || - (TAGNAME(elem) == _nsInfo.xmlNSPrefix + "param") || - (TAGNAME(elem) == _nsInfo.xmlNSPrefix + "donedata") || - (TAGNAME(elem) == _nsInfo.xmlNSPrefix + "datamodel") || - (TAGNAME(elem) == _nsInfo.xmlNSPrefix + "data") || - (TAGNAME(elem) == _nsInfo.xmlNSPrefix + "content")) { + (TAGNAME(elem) == _nsInfo.xmlNSPrefix + "param") || + (TAGNAME(elem) == _nsInfo.xmlNSPrefix + "donedata") || + (TAGNAME(elem) == _nsInfo.xmlNSPrefix + "datamodel") || + (TAGNAME(elem) == _nsInfo.xmlNSPrefix + "data") || + (TAGNAME(elem) == _nsInfo.xmlNSPrefix + "content")) { return; } @@ -168,14 +168,14 @@ void ChartToMinimalSCXML::removeUnvisited(Arabica::DOM::Node<std::string>& node) } } } - + // test344 if (_dmCopy && - TAGNAME(elem) == _nsInfo.xmlNSPrefix + "transition" && - HAS_ATTR(elem, "cond") && - !_dmCopy.isValidSyntax(ATTR(elem, "cond"))) + TAGNAME(elem) == _nsInfo.xmlNSPrefix + "transition" && + HAS_ATTR(elem, "cond") && + !_dmCopy.isValidSyntax(ATTR(elem, "cond"))) return; - + // detach unvisited nodes from DOM if (_visited.find(node) == _visited.end()) { std::cerr << DOMUtils::xPathForNode(node) << std::endl; @@ -198,13 +198,13 @@ void ChartToMinimalSCXML::removeUnvisited(Arabica::DOM::Node<std::string>& node) removeUnvisited(child); } } - + void ChartToMinimalSCXML::markAsVisited(const Arabica::DOM::Element<std::string>& element) { if (_visited.find(element) != _visited.end()) return; - + Arabica::DOM::Element<std::string> elem = const_cast<Arabica::DOM::Element<std::string>&>(element); - + _visited.insert(element); Node<std::string> parent = element.getParentNode(); if (parent && parent.getNodeType() == Node_base::ELEMENT_NODE) { @@ -212,7 +212,7 @@ void ChartToMinimalSCXML::markAsVisited(const Arabica::DOM::Element<std::string> markAsVisited(parentElem); } } - + void ChartToMinimalSCXML::beforeExecutingContent(Interpreter interpreter, const Arabica::DOM::Element<std::string>& element) { markAsVisited(element); StateTransitionMonitor::beforeExecutingContent(interpreter, element); @@ -229,7 +229,7 @@ void ChartToMinimalSCXML::beforeTakingTransition(Interpreter interpreter, const markAsVisited(Arabica::DOM::Element<std::string>(targets[i])); } markAsVisited(transition); - + std::stringstream commentSS; if (HAS_ATTR(transition, "event")) { commentSS << " Step #" << _step++ << " - transition taken for event '" << _currEvent.name << "' "; @@ -244,10 +244,10 @@ void ChartToMinimalSCXML::beforeTakingTransition(Interpreter interpreter, const void ChartToMinimalSCXML::beforeEnteringState(Interpreter interpreter, const Arabica::DOM::Element<std::string>& state, bool moreComing) { markAsVisited(state); - + std::stringstream commentSS; commentSS << " Step #" << _step++ << " - state entered "; - + Arabica::DOM::Element<std::string> ncState = const_cast<Arabica::DOM::Element<std::string>&>(state); if (envVarIsTrue("USCXML_ANNOTATE_PROGRESS")) ncState.insertBefore(_document.createComment(commentSS.str()), ncState.getFirstChild()); diff --git a/src/uscxml/transform/ChartToMinimalSCXML.h b/src/uscxml/transform/ChartToMinimalSCXML.h index 3cdab54..0260ee1 100644 --- a/src/uscxml/transform/ChartToMinimalSCXML.h +++ b/src/uscxml/transform/ChartToMinimalSCXML.h @@ -37,7 +37,7 @@ class USCXML_API ChartToMinimalSCXML : public InterpreterRC, public StateTransit public: virtual ~ChartToMinimalSCXML() {} static Transformer transform(const Interpreter& other); - + // InterpreterMonitor virtual void beforeExecutingContent(Interpreter interpreter, const Arabica::DOM::Element<std::string>& element); virtual void beforeUninvoking(Interpreter interpreter, const Arabica::DOM::Element<std::string>& invokeElem, const std::string& invokeid); @@ -49,33 +49,35 @@ public: // gather executable content per microstep void executeContent(const Arabica::DOM::Element<std::string>& content, bool rethrow = false); - + // invoke and uninvoke virtual void invoke(const Arabica::DOM::Element<std::string>& element); virtual void cancelInvoke(const Arabica::DOM::Element<std::string>& element); protected: void writeTo(std::ostream& stream); - + ChartToMinimalSCXML(const Interpreter& other); - + void markAsVisited(const Arabica::DOM::Element<std::string>& element); void removeUnvisited(Arabica::DOM::Node<std::string>& node); std::set<Arabica::DOM::Node<std::string> > _visited; DataModel _dmCopy; bool _retainAsComments; - + private: size_t _step; - + // we need this to register as an instance at Interpreter::_instances boost::shared_ptr<InterpreterImpl> _selfPtr; - + // prevent deletion from shared_ptr class Deleter { public: - void operator()(ChartToMinimalSCXML* p) { /* do nothing */ } + void operator()(ChartToMinimalSCXML* p) { + /* do nothing */ + } }; }; diff --git a/src/uscxml/transform/ChartToPromela.cpp b/src/uscxml/transform/ChartToPromela.cpp index 03178f0..4e3a990 100644 --- a/src/uscxml/transform/ChartToPromela.cpp +++ b/src/uscxml/transform/ChartToPromela.cpp @@ -109,7 +109,7 @@ for (std::set<int>::iterator transRefIter = transList->transitionRefs.begin(); \ stream << padding << _prefix << "transitions[" << *transRefIter << "] = "#value"; " << std::endl; \ } \ } \ - + #define DUMP_STATS(disregardTime) \ uint64_t now = tthread::chrono::system_clock::now(); \ @@ -142,11 +142,11 @@ void ChartToPromela::writeTo(std::ostream& stream) { writeProgram(stream); } - + void PromelaCodeAnalyzer::addCode(const std::string& code, ChartToPromela* interpreter) { PromelaParser parser(code); // parser.dump(); - + // find all strings std::list<PromelaParserNode*> astNodes; astNodes.push_back(parser.ast); @@ -160,7 +160,7 @@ void PromelaCodeAnalyzer::addCode(const std::string& code, ChartToPromela* inter bool hasValue = false; int assignedValue = 0; - + switch (node->type) { case PML_STRING: { std::string unquoted = node->value; @@ -193,8 +193,8 @@ void PromelaCodeAnalyzer::addCode(const std::string& code, ChartToPromela* inter std::list<PromelaParserNode*>::iterator opIter = node->operands.begin(); if ((*opIter)->type != PML_NAME) { node->dump(); - return; - assert(false); + return; + assert(false); } PromelaTypedef* td = &_typeDefs; @@ -249,14 +249,14 @@ void PromelaCodeAnalyzer::addCode(const std::string& code, ChartToPromela* inter } 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: { @@ -300,7 +300,7 @@ void PromelaCodeAnalyzer::addOrigState(const std::string& stateName) { createMacroName(stateName); } } - + void PromelaCodeAnalyzer::addState(const std::string& stateName) { if (_states.find(stateName) != _states.end()) return; @@ -367,7 +367,7 @@ std::string PromelaCodeAnalyzer::createMacroName(const std::string& literal) { 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); @@ -384,45 +384,45 @@ std::string PromelaCodeAnalyzer::createMacroName(const std::string& literal) { return macroName; } - std::string PromelaCodeAnalyzer::getTypeReset(const std::string& var, const PromelaTypedef& type, const std::string padding) { - std::stringstream assignment; - - std::map<std::string, PromelaTypedef>::const_iterator typeIter = type.types.begin(); - while(typeIter != type.types.end()) { - const PromelaTypedef& innerType = typeIter->second; - if (innerType.arraySize > 0) { - for (int 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(); +std::string PromelaCodeAnalyzer::getTypeReset(const std::string& var, const PromelaTypedef& type, const std::string padding) { + std::stringstream assignment; + + std::map<std::string, PromelaTypedef>::const_iterator typeIter = type.types.begin(); + while(typeIter != type.types.end()) { + const PromelaTypedef& innerType = typeIter->second; + if (innerType.arraySize > 0) { + for (int 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(); } std::string PromelaCodeAnalyzer::getTypeAssignment(const std::string& varTo, const std::string& varFrom, const PromelaTypedef& type, const std::string padding) { - std::stringstream assignment; - - std::map<std::string, PromelaTypedef>::const_iterator typeIter = type.types.begin(); - while(typeIter != type.types.end()) { - const PromelaTypedef& innerType = typeIter->second; - if (innerType.arraySize > 0) { - for (int i = 0; i < innerType.arraySize; i++) { - assignment << padding << varTo << "." << typeIter->first << "[" << i << "] = " << varFrom << "." << typeIter->first << "[" << i << "];" << std::endl; - } - } else if (innerType.types.size() > 0) { - assignment << getTypeAssignment(varTo + "." + typeIter->first, varFrom + "." + typeIter->first, typeIter->second, padding); - } else { - assignment << padding << varTo << "." << typeIter->first << " = " << varFrom << "." << typeIter->first << ";" << std::endl; - } - typeIter++; - } - return assignment.str(); + std::stringstream assignment; + + std::map<std::string, PromelaTypedef>::const_iterator typeIter = type.types.begin(); + while(typeIter != type.types.end()) { + const PromelaTypedef& innerType = typeIter->second; + if (innerType.arraySize > 0) { + for (int i = 0; i < innerType.arraySize; i++) { + assignment << padding << varTo << "." << typeIter->first << "[" << i << "] = " << varFrom << "." << typeIter->first << "[" << i << "];" << std::endl; + } + } else if (innerType.types.size() > 0) { + assignment << getTypeAssignment(varTo + "." + typeIter->first, varFrom + "." + typeIter->first, typeIter->second, padding); + } else { + assignment << padding << varTo << "." << typeIter->first << " = " << varFrom << "." << typeIter->first << ";" << std::endl; + } + typeIter++; + } + return assignment.str(); } std::string PromelaCodeAnalyzer::macroForLiteral(const std::string& literal) { @@ -464,14 +464,14 @@ std::string PromelaCodeAnalyzer::adaptCode(const std::string& code, const std::s posList.sort(); posIter = posList.begin(); lastPos = 0; - + while (posIter != posList.end()) { processedStr << code.substr(lastPos, posIter->first - lastPos) << prefix; lastPos = posIter->first; posIter++; } processedStr << processed.substr(lastPos, processed.size() - lastPos); - + processed = processedStr.str(); processedStr.clear(); processedStr.str(""); @@ -494,12 +494,12 @@ std::string PromelaCodeAnalyzer::adaptCode(const std::string& code, const std::s posIter++; } processedStr << processed.substr(lastPos, processed.size() - lastPos); - + processed = processedStr.str(); processedStr.clear(); processedStr.str(""); } - + return processed; } @@ -507,7 +507,7 @@ std::string PromelaCodeAnalyzer::adaptCode(const std::string& code, const std::s // PromelaParser parsed(expr); // std::list<size_t> posList = getTokenPositions(expr, PML_NAME, parsed.ast); // posList.sort(); -// +// // std::stringstream prefixed; // std::list<size_t>::iterator posIter = posList.begin(); // size_t lastPos = 0; @@ -516,18 +516,18 @@ std::string PromelaCodeAnalyzer::adaptCode(const std::string& code, const std::s // lastPos = *posIter; // posIter++; // } -// +// // prefixed << expr.substr(lastPos, expr.size() - lastPos); // return prefixed.str(); //} - + std::list<std::pair<size_t, size_t> > PromelaCodeAnalyzer::getTokenPositions(const std::string& expr, int type, PromelaParserNode* ast) { std::list<std::pair<size_t, size_t> > 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))) { + ((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) { @@ -549,7 +549,7 @@ std::list<std::pair<size_t, size_t> > PromelaCodeAnalyzer::getTokenPositions(con } return posList; } - + std::set<std::string> PromelaCodeAnalyzer::getEventsWithPrefix(const std::string& prefix) { std::set<std::string> eventNames; std::list<TrieNode*> trieNodes = _eventTrie.getWordsWithPrefix(prefix); @@ -588,14 +588,14 @@ void ChartToPromela::writeEvents(std::ostream& stream) { void ChartToPromela::writeStates(std::ostream& stream) { stream << "/* state name identifiers */" << std::endl; - + std::map<std::string, GlobalState*>::iterator stateIter = _activeConf.begin(); while(stateIter != _activeConf.end()) { stream << "#define " << "s" << stateIter->second->activeIndex << " " << stateIter->second->activeIndex; stream << " /* from \"" << stateIter->first << "\" */" << std::endl; stateIter++; } - + // for (int i = 0; i < _globalConf.size(); i++) { // stream << "#define " << "s" << i << " " << i; // stream << " /* from \"" << ATTR_CAST(_globalStates[i], "id") << "\" */" << std::endl; @@ -637,7 +637,7 @@ void ChartToPromela::writeHistoryArrays(std::ostream& stream) { histNameIter++; } } - + void ChartToPromela::writeTypeDefs(std::ostream& stream) { stream << "/* type definitions */" << std::endl; PromelaCodeAnalyzer::PromelaTypedef typeDefs = _analyzer->getTypes(); @@ -672,7 +672,7 @@ void ChartToPromela::writeTypeDefs(std::ostream& stream) { stream << " int delay;" << std::endl; #if NEW_DELAY_RESHUFFLE #else - stream << " int seqNr;" << std::endl; + stream << " int seqNr;" << std::endl; #endif } stream << " int name;" << std::endl; @@ -682,9 +682,9 @@ void ChartToPromela::writeTypeDefs(std::ostream& stream) { } for (std::map<std::string, PromelaCodeAnalyzer::PromelaTypedef>::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 + tIter->first.compare("seqNr") == 0 || + tIter->first.compare("invokeid") == 0 || + tIter->first.compare("delay") == 0)) { // special treatment for _event continue; } if (currDef.name.compare("_x_t") == 0 && tIter->first.compare("states") == 0) { @@ -729,7 +729,7 @@ std::string ChartToPromela::declForRange(const std::string& identifier, long min return "int " + identifier; return "short " + identifier; } - + // type is definitely positive if (nativeOnly) { if (maxValue > 32767) @@ -768,7 +768,7 @@ std::string ChartToPromela::conditionForHistoryTransition(const GlobalTransition FlatStateIdentifier flatSource(transition->source); FlatStateIdentifier flatTarget(transition->destination); std::string condition; - + return condition; } @@ -777,22 +777,22 @@ std::string ChartToPromela::conditionalizeForHist(GlobalTransition* transition, transitions.insert(transition); return conditionalizeForHist(transitions); } - + std::string ChartToPromela::conditionalizeForHist(const std::set<GlobalTransition*>& transitions, int indent) { std::stringstream condition; std::string memberSep; - + std::set<std::map<std::string, std::list<std::string> > > histSeen; - + for (std::set<GlobalTransition*>::const_iterator transIter = transitions.begin(); transIter != transitions.end(); transIter++) { if ((*transIter)->histTargets.size() == 0) // there are no history transitions in here! continue; - + std::map<std::string, std::list<std::string> > relevantHist; std::map<std::string, std::list<std::string> > currentHist; FlatStateIdentifier flatSource((*transIter)->source); currentHist = flatSource.getHistory(); - + std::set<std::string>::iterator histTargetIter = (*transIter)->histTargets.begin(); while(histTargetIter != (*transIter)->histTargets.end()) { if (currentHist.find(*histTargetIter) != currentHist.end()) { @@ -802,17 +802,17 @@ std::string ChartToPromela::conditionalizeForHist(const std::set<GlobalTransitio } if (relevantHist.size() == 0) continue; - + if (histSeen.find(relevantHist) != histSeen.end()) continue; histSeen.insert(relevantHist); - + std::string itemSep; std::map<std::string, std::list<std::string> >::iterator relevanthistIter = relevantHist.begin(); if (relevantHist.size() > 0) condition << memberSep; - + while(relevanthistIter != relevantHist.end()) { std::list<std::string>::iterator histItemIter = relevanthistIter->second.begin(); while(histItemIter != relevanthistIter->second.end()) { @@ -849,7 +849,7 @@ std::string ChartToPromela::conditionalizeForHist(const std::set<GlobalTransitio // NodeSet<std::string> transitions = filterChildElements(_nsInfo.xmlNSPrefix + "transition", currState); // currState = _globalConf[ATTR_CAST(transitions[0], "target")]; // } -// +// // return content; //} @@ -859,53 +859,53 @@ void ChartToPromela::writeTransition(std::ostream& stream, GlobalTransition* tra padding += " "; } std::list<GlobalTransition*>::const_iterator histIter; - - if (envVarIsTrue("USCXML_ANNOTATE_NOCOMMENT")) { - stream << std::endl << _prefix << "t" << transition->index << ": /* ######################## */ " << std::endl; - - } else { - - stream << std::endl << _prefix << "t" << transition->index << ": /* ######################## " << std::endl; - FlatStateIdentifier flatActiveSource(transition->source); - stream << " from state: "; - PRETTY_PRINT_LIST(stream, flatActiveSource.getActive()); - stream << std::endl; - // stream << " with history: " << flatActiveSource.getFlatHistory() << std::endl; - stream << " ----- on event: " << (transition->eventDesc.size() > 0 ? transition->eventDesc : "SPONTANEOUS") << " --" << std::endl; - stream << " to state: "; - std::set<FlatStateIdentifier> destinations; - destinations.insert(FlatStateIdentifier(transition->destination)); - histIter = transition->historyTrans.begin(); - while(histIter != transition->historyTrans.end()) { - destinations.insert(FlatStateIdentifier((*histIter)->destination)); - histIter++; - } - std::string seperator = ""; - for (std::set<FlatStateIdentifier>::iterator destIter = destinations.begin(); destIter != destinations.end(); destIter++) { - stream << seperator; - PRETTY_PRINT_LIST(stream, destIter->getActive()); - stream << " with " << (destIter->getFlatHistory().size() > 0 ? destIter->getFlatHistory() : "no history"); - seperator = "\n "; - } - stream << std::endl; - - stream << "############################### */" << std::endl; - } - stream << std::endl; + + if (envVarIsTrue("USCXML_ANNOTATE_NOCOMMENT")) { + stream << std::endl << _prefix << "t" << transition->index << ": /* ######################## */ " << std::endl; + + } else { + + stream << std::endl << _prefix << "t" << transition->index << ": /* ######################## " << std::endl; + FlatStateIdentifier flatActiveSource(transition->source); + stream << " from state: "; + PRETTY_PRINT_LIST(stream, flatActiveSource.getActive()); + stream << std::endl; + // stream << " with history: " << flatActiveSource.getFlatHistory() << std::endl; + stream << " ----- on event: " << (transition->eventDesc.size() > 0 ? transition->eventDesc : "SPONTANEOUS") << " --" << std::endl; + stream << " to state: "; + std::set<FlatStateIdentifier> destinations; + destinations.insert(FlatStateIdentifier(transition->destination)); + histIter = transition->historyTrans.begin(); + while(histIter != transition->historyTrans.end()) { + destinations.insert(FlatStateIdentifier((*histIter)->destination)); + histIter++; + } + std::string seperator = ""; + for (std::set<FlatStateIdentifier>::iterator destIter = destinations.begin(); destIter != destinations.end(); destIter++) { + stream << seperator; + PRETTY_PRINT_LIST(stream, destIter->getActive()); + stream << " with " << (destIter->getFlatHistory().size() > 0 ? destIter->getFlatHistory() : "no history"); + seperator = "\n "; + } + stream << std::endl; + + stream << "############################### */" << std::endl; + } + stream << std::endl; stream << padding << "skip;" << std::endl; stream << padding << "d_step {" << std::endl; if (_writeTransitionPrintfs) stream << padding << " printf(\"Taking Transition " << _prefix << "t" << transition->index << "\\n\");" << std::endl; - + padding += " "; indent++; - + // iterators of history transitions executable content std::map<GlobalTransition*, std::pair<GlobalTransition::Action::iter_t, GlobalTransition::Action::iter_t> > actionIters; std::map<GlobalTransition*, std::set<GlobalTransition::Action> > actionsInTransition; typedef std::map<GlobalTransition*, std::pair<GlobalTransition::Action::iter_t, GlobalTransition::Action::iter_t> > actionIters_t; - + histIter = transition->historyTrans.begin(); while(histIter != transition->historyTrans.end()) { actionIters.insert(std::make_pair((*histIter), std::make_pair((*histIter)->actions.begin(), (*histIter)->actions.end()))); @@ -922,16 +922,16 @@ void ChartToPromela::writeTransition(std::ostream& stream, GlobalTransition* tra } // std::copy(transition->actions.begin(), transition->actions.end(), std::inserter(actionsInTransition[transition], actionsInTransition[transition].begin())); - + // GlobalTransition::Action action; std::set<GlobalTransition*> allBut; std::list<ExecContentSeqItem> ecSeq; - + for (std::list<GlobalTransition::Action>::const_iterator actionIter = transition->actions.begin(); actionIter != transition->actions.end(); actionIter++) { // for every executable content in base transition const GlobalTransition::Action& baseAction = *actionIter; allBut.clear(); - + for (actionIters_t::iterator histActionIter = actionIters.begin(); histActionIter != actionIters.end(); histActionIter++) { // iterate every history transition GlobalTransition* histTrans = histActionIter->first; @@ -945,7 +945,7 @@ void ChartToPromela::writeTransition(std::ostream& stream, GlobalTransition* tra if (baseAction != histAction && !baseAction.raiseDone) { // std::cout << baseAction << std::endl; // std::cout << histAction << std::endl; - + // executable content differs - will given executable content appear later in history? if (actionsInTransition[histTrans].find(baseAction) != actionsInTransition[histTrans].end()) { // yes -> write all exec content exclusive to this history transition until base executable content @@ -964,7 +964,7 @@ void ChartToPromela::writeTransition(std::ostream& stream, GlobalTransition* tra histActionIter->second.first++; } } - + if (allBut.empty()) { // everyone has the current actionIter one behind the base action ecSeq.push_back(ExecContentSeqItem(ExecContentSeqItem::EXEC_CONTENT_EVERY, NULL, baseAction)); @@ -973,7 +973,7 @@ void ChartToPromela::writeTransition(std::ostream& stream, GlobalTransition* tra ecSeq.push_back(ExecContentSeqItem(ExecContentSeqItem::EXEC_CONTENT_ALL_BUT, allBut, baseAction)); } } - + // see what remains in history transitions and add as exclusive for (actionIters_t::iterator histActionIter = actionIters.begin(); histActionIter != actionIters.end(); histActionIter++) { GlobalTransition* histTrans = histActionIter->first; @@ -987,7 +987,7 @@ void ChartToPromela::writeTransition(std::ostream& stream, GlobalTransition* tra bool isConditionalized = false; bool wroteHistoryAssignments = false; - + for (std::list<ExecContentSeqItem>::const_iterator ecIter = ecSeq.begin(); ecIter != ecSeq.end(); ecIter++) { const GlobalTransition::Action& action = ecIter->action; @@ -998,11 +998,11 @@ void ChartToPromela::writeTransition(std::ostream& stream, GlobalTransition* tra wroteHistoryAssignments = true; } } - + if (!_analyzer->usesInPredicate() && (action.entered || action.exited)) { continue; } - + if (!isConditionalized && ecIter->type == ExecContentSeqItem::EXEC_CONTENT_ONLY_FOR) { // assert(!wroteHistoryAssignments); // we need to move assignments after dispatching? stream << padding << "if" << std::endl; @@ -1031,18 +1031,18 @@ void ChartToPromela::writeTransition(std::ostream& stream, GlobalTransition* tra case ExecContentSeqItem::EXEC_CONTENT_ONLY_FOR: std::cout << "ONLY_FOR" << std::endl; break; - - default: - break; + + default: + break; } #endif - + if (action.exited) { // we left a state stream << padding << _prefix << "_x.states[" << _analyzer->macroForLiteral(ATTR(action.exited, "id")) << "] = false; " << std::endl; // continue; } - + if (action.entered) { // we entered a state stream << padding << _prefix << "_x.states[" << _analyzer->macroForLiteral(ATTR(action.entered, "id")) << "] = true; " << std::endl; @@ -1055,7 +1055,7 @@ void ChartToPromela::writeTransition(std::ostream& stream, GlobalTransition* tra writeExecutableContent(stream, action.transition, indent); // continue; } - + if (action.onExit) { // std::cout<< action.onExit << std::endl; // executable content from an onexit element @@ -1064,7 +1064,7 @@ void ChartToPromela::writeTransition(std::ostream& stream, GlobalTransition* tra writeExecutableContent(stream, action.onExit, indent); // continue; } - + if (action.onEntry) { // executable content from an onentry element if (action.onEntry.getParentNode()) // this should not be necessary? @@ -1083,7 +1083,7 @@ void ChartToPromela::writeTransition(std::ostream& stream, GlobalTransition* tra if (action.invoke) { // an invoke element - + if (_machines.find(action.invoke) != _machines.end()) { stream << padding << _prefix << "start!" << _analyzer->macroForLiteral(_machines[action.invoke]->_invokerid) << ";" << std::endl; } else { @@ -1093,7 +1093,7 @@ void ChartToPromela::writeTransition(std::ostream& stream, GlobalTransition* tra } } - + if (action.uninvoke) { if (_machines.find(action.uninvoke) != _machines.end()) { stream << padding << "do" << std::endl; @@ -1111,7 +1111,7 @@ void ChartToPromela::writeTransition(std::ostream& stream, GlobalTransition* tra } } } - + if (isConditionalized) { // peek into next content and see if same conditions apply -> keep conditionalization bool sameCondition = false; @@ -1120,7 +1120,7 @@ void ChartToPromela::writeTransition(std::ostream& stream, GlobalTransition* tra if (nextIter != ecSeq.end() && ecIter->type == nextIter->type && ecIter->transitions == nextIter->transitions) { sameCondition = true; } - + if (!sameCondition) { padding = padding.substr(2); indent--; @@ -1137,7 +1137,7 @@ void ChartToPromela::writeTransition(std::ostream& stream, GlobalTransition* tra } } } - + if (!wroteHistoryAssignments) { writeHistoryAssignments(stream, transition, indent); wroteHistoryAssignments = true; @@ -1158,42 +1158,42 @@ void ChartToPromela::writeTransition(std::ostream& stream, GlobalTransition* tra origNewState = _activeConf[transition->activeDestination]; bool hasHistoryTarget = false; - + for (std::map<GlobalState*, std::set<GlobalTransition*> >::const_iterator histTargetIter = histTargets.begin(); histTargetIter != histTargets.end(); histTargetIter++) { GlobalState* histNewState = histTargetIter->first; if (histNewState == origNewState) continue; stream << padding << "if" << std::endl; - if (!envVarIsTrue("USCXML_ANNOTATE_NOCOMMENT")) { - stream << "/* to state "; - FlatStateIdentifier flatActiveDest(histNewState->activeId); - PRETTY_PRINT_LIST(stream, flatActiveDest.getActive()); - stream << " via history */" << std::endl; - } + if (!envVarIsTrue("USCXML_ANNOTATE_NOCOMMENT")) { + stream << "/* to state "; + FlatStateIdentifier flatActiveDest(histNewState->activeId); + PRETTY_PRINT_LIST(stream, flatActiveDest.getActive()); + stream << " via history */" << std::endl; + } - stream << padding << ":: " << conditionalizeForHist(histTargetIter->second) << " -> " << _prefix << "s = s" << histNewState->activeIndex << ";" << std::endl; + stream << padding << ":: " << conditionalizeForHist(histTargetIter->second) << " -> " << _prefix << "s = s" << histNewState->activeIndex << ";" << std::endl; // writeTransitionClosure(stream, *histTargetIter->second.begin(), histNewState, indent + 1); // is this correct for everyone in set? hasHistoryTarget = true; } - + origNewState = _activeConf[transition->activeDestination]; FlatStateIdentifier flatActiveDest(transition->activeDestination); assert(origNewState != NULL); - - if (!envVarIsTrue("USCXML_ANNOTATE_NOCOMMENT")) { - stream << "/* to state "; - PRETTY_PRINT_LIST(stream, flatActiveDest.getActive()); - stream << " */" << std::endl; - } + + if (!envVarIsTrue("USCXML_ANNOTATE_NOCOMMENT")) { + stream << "/* to state "; + PRETTY_PRINT_LIST(stream, flatActiveDest.getActive()); + stream << " */" << std::endl; + } if (hasHistoryTarget) { stream << padding << ":: else -> "; padding += " "; indent++; } - + stream << padding << _prefix << "s = s" << origNewState->activeIndex << ";" << std::endl; @@ -1204,17 +1204,17 @@ void ChartToPromela::writeTransition(std::ostream& stream, GlobalTransition* tra stream << padding << "fi;" << std::endl; } - TRANSITION_TRACE(transition, false); - + TRANSITION_TRACE(transition, false); + padding = padding.substr(2); - stream << padding << "}" << std::endl; + stream << padding << "}" << std::endl; - // moved up here for goto from d_step + // moved up here for goto from d_step writeTransitionClosure(stream, transition, origNewState, indent-1); _perfTransProcessed++; _perfTransTotal++; - + DUMP_STATS(false); } @@ -1224,30 +1224,30 @@ void ChartToPromela::writeHistoryAssignments(std::ostream& stream, GlobalTransit for (int i = 0; i < indent; i++) { padding += " "; } - + if (transition->historyTrans.size() == 0) return; - + // GlobalState to *changed* history configuration std::list<HistoryTransitionClass> histClasses; std::set<GlobalTransition*> allTrans; allTrans.insert(transition); allTrans.insert(transition->historyTrans.begin(), transition->historyTrans.end()); - + // iterate all transitions std::set<GlobalTransition*>::iterator transIter = allTrans.begin(); while(transIter != allTrans.end()) { histClasses.push_back(HistoryTransitionClass(*transIter)); transIter++; } - + // nothing to do here if (histClasses.size() == 0) return; - + // std::cout << histClasses.size() << " / "; - + // now sort into equivalence classes std::list<HistoryTransitionClass>::iterator outerHistClassIter = histClasses.begin(); std::list<HistoryTransitionClass>::iterator innerHistClassIter = histClasses.begin(); @@ -1257,11 +1257,11 @@ void ChartToPromela::writeHistoryAssignments(std::ostream& stream, GlobalTransit // iterate inner iter for every outer iter and see if we can merge innerHistClassIter = outerHistClassIter; innerHistClassIter++; - + while(innerHistClassIter != histClasses.end()) { // can we merge the inner class into the outer one? HistoryTransitionClass& innerClass = *innerHistClassIter; - + if (outerClass.matches(innerClass)) { outerClass.merge(innerClass); histClasses.erase(innerHistClassIter++); @@ -1269,7 +1269,7 @@ void ChartToPromela::writeHistoryAssignments(std::ostream& stream, GlobalTransit innerHistClassIter++; } } - + _perfHistoryProcessed++; _perfHistoryTotal++; @@ -1316,7 +1316,7 @@ void ChartToPromela::writeHistoryAssignments(std::ostream& stream, GlobalTransit forgetIter++; } } - + { std::map<std::string, std::set<std::string> >::iterator rememberIter = histClassIter->toRemember.begin(); while(rememberIter != histClassIter->toRemember.end()) { @@ -1338,11 +1338,11 @@ void ChartToPromela::writeHistoryAssignments(std::ostream& stream, GlobalTransit if (histClassIter == defaultHistClassIter) { break; } - + histClassIter++; } assert(nrMembers == allTrans.size()); - + } HistoryTransitionClass::HistoryTransitionClass(GlobalTransition* transition) { @@ -1357,13 +1357,13 @@ HistoryTransitionClass::HistoryTransitionClass(const std::string& from, const st void HistoryTransitionClass::init(const std::string& from, const std::string& to) { if (from == to) return; - + FlatStateIdentifier flatSource(from); FlatStateIdentifier flatTarget(to); - + std::map<std::string, std::set<std::string> > activeBefore = flatSource.getHistorySets(); std::map<std::string, std::set<std::string> > activeAfter = flatTarget.getHistorySets(); - + std::map<std::string, std::set<std::string> >::const_iterator targetHistIter = activeAfter.begin(); while(targetHistIter != activeAfter.end()) { // for every history state in target, see if it existed in source @@ -1387,7 +1387,7 @@ void HistoryTransitionClass::init(const std::string& from, const std::string& to } sourceHistMemberIter++; } - + std::set<std::string>::const_iterator targetHistMemberIter = activeAfter.at(targetHistIter->first).begin(); while(targetHistMemberIter != activeAfter.at(targetHistIter->first).end()) { // iterate member of target history and see if it is new @@ -1401,7 +1401,7 @@ void HistoryTransitionClass::init(const std::string& from, const std::string& to targetHistIter++; } } - + bool HistoryTransitionClass::matches(const HistoryTransitionClass& other) { /* does the given transition match this one?: @@ -1409,12 +1409,12 @@ bool HistoryTransitionClass::matches(const HistoryTransitionClass& other) { 2. everything forgot has to be forgotten as well or already disabled and vice versa */ - + std::map<std::string, std::set<std::string> > tmp; - + typedef std::map<std::string, std::set<std::string> >::const_iterator histIter_t; typedef std::set<std::string>::const_iterator histMemberIter_t; - + // we will remember these - will the other try to forget them? INTERSECT_MAPS(toRemember, other.toForget, tmp); if (tmp.size() > 0) @@ -1438,9 +1438,9 @@ bool HistoryTransitionClass::matches(const HistoryTransitionClass& other) { void HistoryTransitionClass::merge(const HistoryTransitionClass& other) { members.insert(other.members.begin(), other.members.end()); - + std::map<std::string, std::set<std::string> >::const_iterator histIter; - + histIter = other.toRemember.begin(); while(histIter != other.toRemember.end()) { toRemember[histIter->first].insert(histIter->second.begin(), histIter->second.end()); @@ -1460,7 +1460,7 @@ void HistoryTransitionClass::merge(const HistoryTransitionClass& other) { } } - + void ChartToPromela::writeTransitionClosure(std::ostream& stream, GlobalTransition* transition, GlobalState* state, int indent) { std::string padding; for (int i = 0; i < indent; i++) { @@ -1491,12 +1491,12 @@ void ChartToPromela::writeExecutableContent(std::ostream& stream, const Arabica: for (int i = 0; i < indent; i++) { padding += " "; } - + if (node.getNodeType() == Node_base::TEXT_NODE) { if (boost::trim_copy(node.getNodeValue()).length() > 0) stream << beautifyIndentation(ADAPT_SRC(node.getNodeValue()), indent) << std::endl; } - + if (node.getNodeType() != Node_base::ELEMENT_NODE) return; // skip anything not an element @@ -1515,17 +1515,17 @@ void ChartToPromela::writeExecutableContent(std::ostream& stream, const Arabica: for (int i = 0; i < scriptText.size(); i++) { stream << ADAPT_SRC(beautifyIndentation(scriptText[i].getNodeValue(), indent)) << std::endl; } - + } else if(TAGNAME(nodeElem) == "log") { std::string label = (HAS_ATTR(nodeElem, "label") ? ATTR(nodeElem, "label") : ""); std::string expr = (HAS_ATTR(nodeElem, "expr") ? ADAPT_SRC(ATTR(nodeElem, "expr")) : ""); std::string trimmedExpr = boost::trim_copy(expr); bool isStringLiteral = (boost::starts_with(trimmedExpr, "\"") || boost::starts_with(trimmedExpr, "'")); - + std::string formatString; std::string varString; std::string seperator; - + if (label.size() > 0) { if (expr.size() > 0) { formatString += label + ": "; @@ -1533,20 +1533,20 @@ void ChartToPromela::writeExecutableContent(std::ostream& stream, const Arabica: 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(nodeElem) == "foreach") { stream << padding << "for (" << _prefix << (HAS_ATTR(nodeElem, "index") ? ATTR(nodeElem, "index") : "_index") << " in " << _prefix << ATTR(nodeElem, "array") << ") {" << std::endl; if (HAS_ATTR(nodeElem, "item")) { @@ -1560,23 +1560,23 @@ void ChartToPromela::writeExecutableContent(std::ostream& stream, const Arabica: // if (HAS_ATTR(nodeElem, "index")) // stream << padding << " " << _prefix << ATTR(nodeElem, "index") << "++;" << std::endl; stream << padding << "}" << std::endl; - + } else if(TAGNAME(nodeElem) == "if") { NodeSet<std::string> condChain; condChain.push_back(node); condChain.push_back(filterChildElements(_nsInfo.xmlNSPrefix + "elseif", node)); condChain.push_back(filterChildElements(_nsInfo.xmlNSPrefix + "else", node)); - + writeIfBlock(stream, condChain, indent); - + } else if(TAGNAME(nodeElem) == "assign") { NodeSet<std::string> assignTexts = filterChildType(Node_base::TEXT_NODE, nodeElem, true); assert(assignTexts.size() > 0); stream << beautifyIndentation(ADAPT_SRC(boost::trim_copy(assignTexts[0].getNodeValue())), indent) << std::endl; - + } else if(TAGNAME(nodeElem) == "send" || TAGNAME(nodeElem) == "raise") { std::string targetQueue; - std::string insertOp = "!"; + std::string insertOp = "!"; if (TAGNAME(nodeElem) == "raise") { targetQueue = _prefix + "iQ"; } else if (!HAS_ATTR(nodeElem, "target")) { @@ -1595,7 +1595,7 @@ void ChartToPromela::writeExecutableContent(std::ostream& stream, const Arabica: if (targetQueue.length() > 0) { // this is for our external queue std::string event; - + if (HAS_ATTR(nodeElem, "event")) { event = _analyzer->macroForLiteral(ATTR(nodeElem, "event")); } else if (HAS_ATTR(nodeElem, "eventexpr")) { @@ -1603,10 +1603,10 @@ void ChartToPromela::writeExecutableContent(std::ostream& stream, const Arabica: } if (_analyzer->usesComplexEventStruct()) { stream << padding << "{" << std::endl; - std::string typeReset = _analyzer->getTypeReset("tmpE", _analyzer->getType("_event"), padding + " "); - std::stringstream typeAssignSS; - typeAssignSS << padding << " tmpE.name = " << event << ";" << std::endl; - + std::string typeReset = _analyzer->getTypeReset("tmpE", _analyzer->getType("_event"), padding + " "); + std::stringstream typeAssignSS; + typeAssignSS << padding << " tmpE.name = " << event << ";" << std::endl; + if (HAS_ATTR(nodeElem, "idlocation")) { typeAssignSS << padding << " /* idlocation */" << std::endl; typeAssignSS << padding << " _lastSendId = _lastSendId + 1;" << std::endl; @@ -1619,11 +1619,11 @@ void ChartToPromela::writeExecutableContent(std::ostream& stream, const Arabica: } else if (HAS_ATTR(nodeElem, "id")) { typeAssignSS << padding << " tmpE.sendid = " << _analyzer->macroForLiteral(ATTR(nodeElem, "id")) << ";" << std::endl; } - + if (_invokerid.length() > 0) { // do not send invokeid if we send / raise to ourself typeAssignSS << padding << " tmpE.invokeid = " << _analyzer->macroForLiteral(_invokerid) << ";" << std::endl; } - + if (_analyzer->usesEventField("origintype") && !boost::ends_with(targetQueue, "iQ")) { typeAssignSS << padding << " tmpE.origintype = " << _analyzer->macroForLiteral("http://www.w3.org/TR/scxml/#SCXMLEventProcessor") << ";" << std::endl; } @@ -1631,7 +1631,7 @@ void ChartToPromela::writeExecutableContent(std::ostream& stream, const Arabica: if (_analyzer->usesEventField("delay")) { #if NEW_DELAY_RESHUFFLE #else - insertOp += "!"; + insertOp += "!"; typeAssignSS << padding << " _lastSeqId = _lastSeqId + 1;" << std::endl; #endif if (HAS_ATTR_CAST(nodeElem, "delay")) { @@ -1643,7 +1643,7 @@ void ChartToPromela::writeExecutableContent(std::ostream& stream, const Arabica: } #if NEW_DELAY_RESHUFFLE #else - typeAssignSS << padding << " tmpE.seqNr = _lastSeqId;" << std::endl; + typeAssignSS << padding << " tmpE.seqNr = _lastSeqId;" << std::endl; #endif } @@ -1651,7 +1651,7 @@ void ChartToPromela::writeExecutableContent(std::ostream& stream, const Arabica: std::string eventType = (targetQueue.compare("iQ!") == 0 ? _analyzer->macroForLiteral("internal") : _analyzer->macroForLiteral("external")); typeAssignSS << padding << " tmpE.type = " << eventType << ";" << std::endl; } - + NodeSet<std::string> sendParams = filterChildElements(_nsInfo.xmlNSPrefix + "param", nodeElem); NodeSet<std::string> sendContents = filterChildElements(_nsInfo.xmlNSPrefix + "content", nodeElem); std::string sendNameList = ATTR(nodeElem, "namelist"); @@ -1669,7 +1669,7 @@ void ChartToPromela::writeExecutableContent(std::ostream& stream, const Arabica: nameIter++; } } - + if (sendParams.size() == 0 && sendNameList.size() == 0 && sendContents.size() > 0) { Element<std::string> contentElem = Element<std::string>(sendContents[0]); if (contentElem.hasChildNodes() && contentElem.getFirstChild().getNodeType() == Node_base::TEXT_NODE) { @@ -1683,8 +1683,8 @@ void ChartToPromela::writeExecutableContent(std::ostream& stream, const Arabica: typeAssignSS << padding << " tmpE.data = " << ADAPT_SRC(ATTR(contentElem, "expr")) << ";" << std::endl; } } - - // remove all fields from typeReset that are indeed set by typeAssign + + // 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('.')); @@ -1697,28 +1697,28 @@ void ChartToPromela::writeExecutableContent(std::ostream& stream, const Arabica: // } // 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(); - - + std::istringstream typeResetSS (typeReset); + for (std::string reset; std::getline(typeResetSS, reset); ) { + std::string resetField = reset.substr(0, reset.find('=')); + resetField = resetField.substr(resetField.find('.')); + for (std::string assigned; std::getline(typeAssignSS, assigned); ) { + if (boost::find_first(resetField, assigned)) { + break; + } + } + stream << reset << std::endl; + } + stream << typeAssignSS.str(); + + stream << padding << " " << targetQueue << insertOp <<"tmpE;" << std::endl; - + #if NEW_DELAY_RESHUFFLE - if (_analyzer->usesEventField("delay") && !boost::ends_with(targetQueue, "iQ")) { - stream << padding << " insertWithDelay(" << targetQueue << ");" << std::endl; - } + 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; @@ -1742,7 +1742,7 @@ PromelaInlines::~PromelaInlines() { std::list<PromelaInline*> PromelaInlines::getRelatedTo(const Arabica::DOM::Node<std::string>& node, PromelaInline::PromelaInlineType type) { std::list<PromelaInline*> related; - + std::map<Arabica::DOM::Node<std::string>, std::list<PromelaInline*> >::iterator inlIter = inlines.begin(); while (inlIter != inlines.end()) { std::list<PromelaInline*>::iterator pmlIter = inlIter->second.begin(); @@ -1761,7 +1761,7 @@ std::list<PromelaInline*> PromelaInlines::getRelatedTo(const Arabica::DOM::Node< std::list<PromelaInline*> PromelaInlines::getAllOfType(uint32_t type) { std::list<PromelaInline*> related; - + std::map<Arabica::DOM::Node<std::string>, std::list<PromelaInline*> >::iterator inlIter = inlines.begin(); while (inlIter != inlines.end()) { std::list<PromelaInline*>::iterator pmlIter = inlIter->second.begin(); @@ -1782,7 +1782,7 @@ PromelaInline::PromelaInline(const Arabica::DOM::Node<std::string>& node) : prev std::stringstream ssLine(node.getNodeValue()); std::string line; - + while(std::getline(ssLine, line)) { // skip to first promela line boost::trim(line); @@ -1812,13 +1812,13 @@ PromelaInline::PromelaInline(const Arabica::DOM::Node<std::string>& node) : prev 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")) { @@ -1835,14 +1835,14 @@ PromelaInline::PromelaInline(const Arabica::DOM::Node<std::string>& node) : prev PromelaInlines::PromelaInlines(const Arabica::DOM::Node<std::string>& node) { NodeSet<std::string> levelNodes; levelNodes.push_back(node); - + size_t level = 0; while(levelNodes.size() > 0) { PromelaInline* predecessor = NULL; // iterate all nodes at given level for (int i = 0; i < levelNodes.size(); i++) { - + // get all comments NodeSet<std::string> comments = InterpreterImpl::filterChildType(Node_base::COMMENT_NODE, levelNodes[i]); for (int j = 0; j < comments.size(); j++) { @@ -1863,7 +1863,7 @@ PromelaInlines::PromelaInlines(const Arabica::DOM::Node<std::string>& node) { allInlines.push_back(tmp); } } - + levelNodes = InterpreterImpl::filterChildType(Node_base::ELEMENT_NODE, levelNodes); level++; } @@ -1872,32 +1872,32 @@ PromelaInlines::PromelaInlines(const Arabica::DOM::Node<std::string>& node) { void PromelaInline::dump() { #if 0 switch(type) { - case PROMELA_NIL: - std::cerr << "PROMELA_NIL" << std::endl; - break; - case PROMELA_CODE: - std::cerr << "PROMELA_CODE" << std::endl; - break; - case PROMELA_EVENT_SOURCE_ALL: - std::cerr << "PROMELA_EVENT_SOURCE" << std::endl; - break; - case PROMELA_INVOKER: - std::cerr << "PROMELA_INVOKER" << std::endl; - break; - case PROMELA_PROGRESS_LABEL: - std::cerr << "PROMELA_PROGRESS_LABEL" << std::endl; - break; - case PROMELA_ACCEPT_LABEL: - std::cerr << "PROMELA_ACCEPT_LABEL" << std::endl; - break; - case PROMELA_END_LABEL: - std::cerr << "PROMELA_END_LABEL" << std::endl; - break; + case PROMELA_NIL: + std::cerr << "PROMELA_NIL" << std::endl; + break; + case PROMELA_CODE: + std::cerr << "PROMELA_CODE" << std::endl; + break; + case PROMELA_EVENT_SOURCE_ALL: + std::cerr << "PROMELA_EVENT_SOURCE" << std::endl; + break; + case PROMELA_INVOKER: + std::cerr << "PROMELA_INVOKER" << std::endl; + break; + case PROMELA_PROGRESS_LABEL: + std::cerr << "PROMELA_PROGRESS_LABEL" << std::endl; + break; + case PROMELA_ACCEPT_LABEL: + std::cerr << "PROMELA_ACCEPT_LABEL" << std::endl; + break; + case PROMELA_END_LABEL: + std::cerr << "PROMELA_END_LABEL" << std::endl; + break; } #endif } - + void ChartToPromela::writeIfBlock(std::ostream& stream, const Arabica::XPath::NodeSet<std::string>& condChain, int indent) { if (condChain.size() == 0) return; @@ -2014,10 +2014,10 @@ void ChartToPromela::writeStrings(std::ostream& stream) { void ChartToPromela::writeDeclarations(std::ostream& stream) { stream << "/* global variables " << (_prefix.size() > 0 ? "for " + _prefix : "") << " */" << std::endl; - + // we cannot know our event queue with nested invokers? Adding some for test422 size_t tolerance = 6; - + if (_analyzer->usesComplexEventStruct()) { // event is defined with the typedefs stream << "_event_t " << _prefix << "_event; /* current event */" << std::endl; @@ -2038,7 +2038,7 @@ void ChartToPromela::writeDeclarations(std::ostream& stream) { if (_machines.size() > 0) { stream << "chan " << _prefix << "start = [" << _machines.size() << "] of {int} /* nested machines to start at next macrostep */" << std::endl; } - + if (_hasIndexLessLoops) stream << "hidden int " << _prefix << "_index; /* helper for indexless foreach loops */" << std::endl; @@ -2054,7 +2054,7 @@ void ChartToPromela::writeDeclarations(std::ostream& stream) { stream << "hidden _ioprocessors_t " << _prefix << "_ioprocessors;" << std::endl; _varInitializers.push_front("_ioprocessors.scxml.location = " + (_invokerid.size() > 0 ? _analyzer->macroForLiteral(_invokerid) : "1") + ";"); } - + if (_prefix.size() == 0 || _prefix == "MAIN_") { if (_analyzer->usesEventField("sendid")) { // stream << "chan sendIdQ = [" << MAX(_externalQueueLength + 1, 1) << "] of {_event_t} /* temporary queue to cancel events per sendidexpr */" << std::endl; @@ -2087,33 +2087,33 @@ void ChartToPromela::writeDeclarations(std::ostream& stream) { // get all data elements NodeSet<std::string> datas = _xpath.evaluate("//" + _nsInfo.xpathPrefix + "data", _scxml).asNodeSet(); - + // write their text content stream << "/* data model variables" << (_prefix.size() > 0 ? " for " + _prefix : "") << " */" << std::endl; std::set<std::string> processedIdentifiers; - + // automatic types PromelaCodeAnalyzer::PromelaTypedef allTypes = _analyzer->getTypes(); for (int i = 0; i < datas.size(); i++) { - + Node<std::string> data = datas[i]; if (isInEmbeddedDocument(data)) continue; - + std::string identifier = (HAS_ATTR_CAST(data, "id") ? ATTR_CAST(data, "id") : ""); std::string 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; @@ -2122,7 +2122,7 @@ void ChartToPromela::writeDeclarations(std::ostream& stream) { continue; } } - + std::string arrSize; size_t bracketPos = type.find("["); if (bracketPos != std::string::npos) { @@ -2133,8 +2133,8 @@ void ChartToPromela::writeDeclarations(std::ostream& stream) { stream << decl << ";" << std::endl; } - - + + // implicit and dynamic types std::map<std::string, PromelaCodeAnalyzer::PromelaTypedef>::iterator typeIter = allTypes.types.begin(); while(typeIter != allTypes.types.end()) { @@ -2142,23 +2142,23 @@ void ChartToPromela::writeDeclarations(std::ostream& stream) { typeIter++; continue; } - + if (processedIdentifiers.find(typeIter->first) != processedIdentifiers.end()) { typeIter++; continue; } - + if (typeIter->first == "_event" || - typeIter->first == "_x" || - typeIter->first == "_ioprocessors" || - typeIter->first == "_SESSIONID" || - typeIter->first == "_NAME") { + typeIter->first == "_x" || + typeIter->first == "_ioprocessors" || + typeIter->first == "_SESSIONID" || + typeIter->first == "_NAME") { 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 { @@ -2168,7 +2168,7 @@ void ChartToPromela::writeDeclarations(std::ostream& stream) { } stream << std::endl; - + } void ChartToPromela::writeEventSources(std::ostream& stream) { @@ -2189,7 +2189,7 @@ void ChartToPromela::writeStartInvoker(std::ostream& stream, const Arabica::DOM: } } } - + // set from params NodeSet<std::string> invokeParams = filterChildElements(_nsInfo.xmlNSPrefix + "param", node); for (int i = 0; i < invokeParams.size(); i++) { @@ -2199,7 +2199,7 @@ void ChartToPromela::writeStartInvoker(std::ostream& stream, const Arabica::DOM: stream << padding << invoker->_prefix << identifier << " = " << ADAPT_SRC(expression) << ";" << std::endl; } } - + stream << padding << "run " << invoker->_prefix << "run() priority 20;" << std::endl; if (HAS_ATTR_CAST(node, "idlocation")) { stream << padding << ADAPT_SRC(ATTR_CAST(node, "idlocation")) << " = " << _analyzer->macroForLiteral(invoker->_invokerid) << ";" << std::endl; @@ -2211,12 +2211,12 @@ void ChartToPromela::writeFSM(std::ostream& stream) { NodeSet<std::string> transitions; stream << "proctype " << (_prefix.size() == 0 ? "machine_" : _prefix) << "run() {" << std::endl; - stream << " d_step {" << std::endl; - stream << " " << _prefix << "done = false;" << std::endl; + stream << " d_step {" << std::endl; + stream << " " << _prefix << "done = false;" << std::endl; stream << " " << _prefix << "canceled = false;" << std::endl; stream << " " << _prefix << "spontaneous = true;" << std::endl; stream << " " << _prefix << "procid = _pid;" << std::endl; - stream << " }" << std::endl; + stream << " }" << std::endl; // write initial transition // transitions = filterChildElements(_nsInfo.xmlNSPrefix + "transition", _startState); // assert(transitions.size() == 1); @@ -2229,13 +2229,13 @@ void ChartToPromela::writeFSM(std::ostream& stream) { } stream << std::endl; } - + stream << std::endl << "/* transition to initial state */" << std::endl; assert(_start->sortedOutgoing.size() == 1); // initial transition has to be first one for control flow at start writeTransition(stream, _start->sortedOutgoing.front(), 1); stream << std::endl; - + // every other transition for (std::map<std::string, GlobalState*>::iterator stateIter = _activeConf.begin(); stateIter != _activeConf.end(); stateIter++) { for (std::list<GlobalTransition*>::iterator transIter = stateIter->second->sortedOutgoing.begin(); transIter != stateIter->second->sortedOutgoing.end(); transIter++) { @@ -2255,7 +2255,7 @@ void ChartToPromela::writeFSM(std::ostream& stream) { } _perfStatesProcessed++; _perfStatesTotal++; - + DUMP_STATS(false); } DUMP_STATS(true); @@ -2269,15 +2269,15 @@ void ChartToPromela::writeFSM(std::ostream& stream) { #if NEW_DELAY_RESHUFFLE stream << " :: len(" << _prefix << "tmpQ) != 0 -> { " << _prefix << "tmpQ?" << _prefix << "_event; " << _prefix << "eQ!" << _prefix << "_event; insertWithDelay(" << _prefix << "eQ); }" << std::endl; #else - stream << " :: len(" << _prefix << "tmpQ) != 0 -> { " << _prefix << "tmpQ?" << _prefix << "_event; " << _prefix << "eQ!!" << _prefix << "_event }" << std::endl; + stream << " :: len(" << _prefix << "tmpQ) != 0 -> { " << _prefix << "tmpQ?" << _prefix << "_event; " << _prefix << "eQ!!" << _prefix << "_event }" << std::endl; #endif - } else { + } else { stream << " :: len(" << _prefix << "tmpQ) != 0 -> { " << _prefix << "tmpQ?" << _prefix << "_event; " << _prefix << "eQ!" << _prefix << "_event }" << std::endl; } stream << " :: else -> break;" << std::endl; stream << " od;" << std::endl << std::endl; } - + if (_machines.size() > 0) { stream << " /* start pending invokers */" << std::endl; stream << " int invokerId;" << std::endl; @@ -2295,15 +2295,15 @@ void ChartToPromela::writeFSM(std::ostream& stream) { stream << " :: else -> break;" << std::endl; stream << " od" << std::endl << std::endl; } - + if (_analyzer->usesEventField("delay") && _machinesAll->size() > 1) { stream << "/* Determine machines with smallest delay and set their process priority */" << std::endl; stream << " scheduleMachines();" << std::endl << std::endl; } - + std::list<PromelaInline*> eventSources = pmlInlines.getAllOfType(PromelaInline::PROMELA_EVENT_ALL_BUT | - PromelaInline::PROMELA_EVENT_ONLY); - + PromelaInline::PROMELA_EVENT_ONLY); + stream << " atomic {" << std::endl; stream << "/* pop an event */" << std::endl; stream << " if" << std::endl; @@ -2318,7 +2318,7 @@ void ChartToPromela::writeFSM(std::ostream& stream) { PromelaEventSource es(**esIter); std::string condition = "true"; - + if (LOCALNAME(es.container) == "invoke") { if (HAS_ATTR_CAST(es.container, "id")) { condition = _prefix + ATTR_CAST(es.container, "id") + "Running"; @@ -2329,13 +2329,13 @@ void ChartToPromela::writeFSM(std::ostream& stream) { condition = _prefix + "_x.states[" + _analyzer->macroForLiteral(ATTR(es.container, "id")) + "]"; } stream << " :: " << condition << " -> {" << std::endl; - + if (es.type == PromelaInline::PROMELA_EVENT_ALL_BUT) { std::string excludeEventDescs; for (std::list<Data>::iterator evIter = es.events.array.begin(); evIter != es.events.array.end(); evIter++) { excludeEventDescs += " " + evIter->atom; } - + NodeSet<std::string> transitions = filterChildElements("transition", es.container, true); std::set<std::string> eventNames; for (int i = 0; i < transitions.size(); i++) { @@ -2365,7 +2365,7 @@ void ChartToPromela::writeFSM(std::ostream& stream) { } stream << " fi " << std::endl; } - + } else if (es.type == PromelaInline::PROMELA_EVENT_ONLY) { if (es.events.array.size() > 0) { stream << " if " << std::endl; @@ -2383,7 +2383,7 @@ void ChartToPromela::writeFSM(std::ostream& stream) { } stream << " }" << std::endl; } - + stream << " fi" << std::endl; stream << " }" << std::endl; } else { @@ -2391,7 +2391,7 @@ void ChartToPromela::writeFSM(std::ostream& stream) { } stream << " fi;" << std::endl << std::endl; - + stream << "/* terminate if we are stopped */" << std::endl; stream << " if" << std::endl; stream << " :: " << _prefix << "done -> goto " << _prefix << "terminate;" << std::endl; @@ -2425,7 +2425,7 @@ void ChartToPromela::writeFSM(std::ostream& stream) { stream << " fi;" << std::endl << std::endl; } } - + for (std::map<Arabica::DOM::Node<std::string>, ChartToPromela*>::iterator invIter = _machines.begin(); invIter != _machines.end(); invIter++) { if (invIter->second == this) { continue; @@ -2437,16 +2437,16 @@ void ChartToPromela::writeFSM(std::ostream& stream) { stream << " :: " << invIter->second->_prefix << "done -> skip;" << std::endl; stream << " :: " << invIter->second->_prefix << "canceled -> skip;" << std::endl; #if NEW_DELAY_RESHUFFLE - stream << " :: else -> { " << invIter->second->_prefix << "eQ!" << _prefix << "_event" << "; insertWithDelay(" << invIter->second->_prefix << "eQ" << "); }" << std::endl; + stream << " :: else -> { " << invIter->second->_prefix << "eQ!" << _prefix << "_event" << "; insertWithDelay(" << invIter->second->_prefix << "eQ" << "); }" << std::endl; #else - stream << " :: else -> { " << invIter->second->_prefix << "eQ!!" << _prefix << "_event" << " }" << std::endl; + stream << " :: else -> { " << invIter->second->_prefix << "eQ!!" << _prefix << "_event" << " }" << std::endl; #endif stream << " fi;" << std::endl << std::endl; } } stream << std::endl; - + stream << _prefix << "microStep:" << std::endl; stream << "/* event dispatching per state */" << std::endl; stream << " if" << std::endl; @@ -2461,22 +2461,22 @@ void ChartToPromela::writeFSM(std::ostream& stream) { if (_parent != NULL) { stream << " {" << std::endl; - stream << _analyzer->getTypeReset("tmpE", _analyzer->getType("_event"), " "); + stream << _analyzer->getTypeReset("tmpE", _analyzer->getType("_event"), " "); stream << " tmpE.name = " << _analyzer->macroForLiteral("done.invoke." + _invokerid) << ";" << std::endl; if (_invokerid.length() > 0) { stream << " tmpE.invokeid = " << _analyzer->macroForLiteral(_invokerid) << ";" << std::endl; } if (_analyzer->usesEventField("delay")) { #if NEW_DELAY_RESHUFFLE - stream << " " << _parent->_prefix << "eQ!tmpE;" << std::endl; - stream << " insertWithDelay(" << _parent->_prefix << "eQ);" << std::endl; - + stream << " " << _parent->_prefix << "eQ!tmpE;" << std::endl; + stream << " insertWithDelay(" << _parent->_prefix << "eQ);" << std::endl; + #else - stream << " _lastSeqId = _lastSeqId + 1;" << std::endl; - stream << " tmpE.seqNr = _lastSeqId;" << std::endl; - stream << " " << _parent->_prefix << "eQ!!tmpE;" << std::endl; + stream << " _lastSeqId = _lastSeqId + 1;" << std::endl; + stream << " tmpE.seqNr = _lastSeqId;" << std::endl; + stream << " " << _parent->_prefix << "eQ!!tmpE;" << std::endl; #endif - } else { + } else { stream << " " << _parent->_prefix << "eQ!tmpE;" << std::endl; } stream << " }" << std::endl; @@ -2484,7 +2484,7 @@ void ChartToPromela::writeFSM(std::ostream& stream) { if (_analyzer->usesEventField("delay")) stream << " removePendingEventsForInvoker(" << _analyzer->macroForLiteral(this->_invokerid) << ")" << std::endl; } - + stream << " }" << std::endl; stream << "}" << std::endl; } @@ -2525,7 +2525,7 @@ void ChartToPromela::writeRescheduleProcess(std::ostream& stream, int indent) { stream << padding << " fi;" << std::endl; stream << padding << " }" << std::endl; } - + stream << padding << " :: else -> skip;" << std::endl; stream << padding << " fi;" << std::endl; stream << padding << " }" << std::endl; @@ -2555,97 +2555,97 @@ void ChartToPromela::writeDetermineShortestDelay(std::ostream& stream, int inden } void ChartToPromela::writeInsertWithDelay(std::ostream& stream, int indent) { - std::string padding; - for (int i = 0; i < indent; i++) { - padding += " "; - } - - uint32_t maxExternalQueueLength = 1; - std::map<Arabica::DOM::Node<std::string>, ChartToPromela*>::iterator machineIter = _machinesAll->begin(); - while(machineIter != _machinesAll->end()) { - maxExternalQueueLength = MAX(maxExternalQueueLength, machineIter->second->_externalQueueLength); - machineIter++; - } - - maxExternalQueueLength += 6; - - if (maxExternalQueueLength <= 1) { - stream << padding << "/* noop for external queues with length <= 1 */" << std::endl; - stream << padding << "inline insertWithDelay(queue) {}" << std::endl; - } - - stream << padding << "hidden _event_t _iwdQ[" << maxExternalQueueLength - 1 << "];" << std::endl; - stream << padding << "hidden int _iwdQLength = 0;" << std::endl; - stream << padding << "hidden int _iwdIdx1 = 0;" << std::endl; - stream << padding << "hidden int _iwdIdx2 = 0;" << std::endl; - stream << padding << "hidden _event_t _iwdTmpE;" << std::endl; - stream << padding << "hidden _event_t _iwdLastE;" << std::endl; - stream << padding << "bool _iwdInserted = false;" << std::endl; - stream << padding << "" << std::endl; - stream << padding << "/* last event in given queue is potentially at wrong position */" << std::endl; - stream << padding << "inline insertWithDelay(queue) {" << std::endl; - stream << padding << " d_step {" << std::endl; - stream << padding << "" << std::endl; - stream << padding << " /* only process for non-trivial queues */" << std::endl; - stream << padding << " if" << std::endl; - stream << padding << " :: len(queue) > 1 -> {" << std::endl; - stream << padding << "" << std::endl; - stream << padding << " /* move all events but last over and remember the last one */" << std::endl; - stream << padding << " _iwdIdx1 = 0;" << std::endl; - stream << padding << " _iwdQLength = len(queue) - 1;" << std::endl; - stream << padding << "" << std::endl; - stream << padding << " do" << std::endl; - stream << padding << " :: _iwdIdx1 < _iwdQLength -> {" << std::endl; - stream << padding << " queue?_iwdTmpE;" << std::endl; - stream << padding << " _iwdQ[_iwdIdx1].name = _iwdTmpE.name;" << std::endl; - - stream << _analyzer->getTypeAssignment("_iwdQ[_iwdIdx1]", "_iwdTmpE", _analyzer->getType("_event"), padding + " "); - - stream << padding << " _iwdIdx1++;" << std::endl; - stream << padding << " }" << std::endl; - stream << padding << " :: else -> break;" << std::endl; - stream << padding << " od" << std::endl; - stream << padding << "" << std::endl; - stream << padding << " queue?_iwdLastE;" << std::endl; - stream << padding << "" << std::endl; - stream << padding << " /* _iwdQ now contains all but last item in _iwdLastE */" << std::endl; - stream << padding << " assert(len(queue) == 0);" << std::endl; - stream << padding << "" << std::endl; - stream << padding << " /* reinsert into queue and place _iwdLastE correctly */" << std::endl; - stream << padding << " _iwdInserted = false;" << std::endl; - stream << padding << " _iwdIdx2 = 0;" << std::endl; - stream << padding << "" << std::endl; - stream << padding << " do" << std::endl; - stream << padding << " :: _iwdIdx2 < _iwdIdx1 -> {" << std::endl; - stream << padding << " _iwdTmpE.name = _iwdQ[_iwdIdx2].name;" << std::endl; - - stream << _analyzer->getTypeAssignment("_iwdTmpE", "_iwdQ[_iwdIdx2]", _analyzer->getType("_event"), padding + " "); - - stream << padding << "" << std::endl; - stream << padding << " if" << std::endl; - stream << padding << " :: _iwdTmpE.delay > _iwdLastE.delay -> {" << std::endl; - stream << padding << " queue!_iwdLastE;" << std::endl; - stream << padding << " _iwdInserted = true;" << std::endl; - stream << padding << " }" << std::endl; - stream << padding << " :: else -> skip" << std::endl; - stream << padding << " fi;" << std::endl; - stream << padding << "" << std::endl; - stream << padding << " queue!_iwdTmpE;" << std::endl; - stream << padding << " _iwdIdx2++;" << std::endl; - stream << padding << " }" << std::endl; - stream << padding << " :: else -> break;" << std::endl; - stream << padding << " od" << std::endl; - stream << padding << "" << std::endl; - stream << padding << " if" << std::endl; - stream << padding << " :: !_iwdInserted -> queue!_iwdLastE;" << std::endl; - stream << padding << " :: else -> skip;" << std::endl; - stream << padding << " fi;" << std::endl; - stream << padding << "" << std::endl; - stream << padding << " }" << std::endl; - stream << padding << " :: else -> skip;" << std::endl; - stream << padding << " fi;" << std::endl; - stream << padding << " }" << std::endl; - stream << padding << "}" << std::endl; + std::string padding; + for (int i = 0; i < indent; i++) { + padding += " "; + } + + uint32_t maxExternalQueueLength = 1; + std::map<Arabica::DOM::Node<std::string>, ChartToPromela*>::iterator machineIter = _machinesAll->begin(); + while(machineIter != _machinesAll->end()) { + maxExternalQueueLength = MAX(maxExternalQueueLength, machineIter->second->_externalQueueLength); + machineIter++; + } + + maxExternalQueueLength += 6; + + if (maxExternalQueueLength <= 1) { + stream << padding << "/* noop for external queues with length <= 1 */" << std::endl; + stream << padding << "inline insertWithDelay(queue) {}" << std::endl; + } + + stream << padding << "hidden _event_t _iwdQ[" << maxExternalQueueLength - 1 << "];" << std::endl; + stream << padding << "hidden int _iwdQLength = 0;" << std::endl; + stream << padding << "hidden int _iwdIdx1 = 0;" << std::endl; + stream << padding << "hidden int _iwdIdx2 = 0;" << std::endl; + stream << padding << "hidden _event_t _iwdTmpE;" << std::endl; + stream << padding << "hidden _event_t _iwdLastE;" << std::endl; + stream << padding << "bool _iwdInserted = false;" << std::endl; + stream << padding << "" << std::endl; + stream << padding << "/* last event in given queue is potentially at wrong position */" << std::endl; + stream << padding << "inline insertWithDelay(queue) {" << std::endl; + stream << padding << " d_step {" << std::endl; + stream << padding << "" << std::endl; + stream << padding << " /* only process for non-trivial queues */" << std::endl; + stream << padding << " if" << std::endl; + stream << padding << " :: len(queue) > 1 -> {" << std::endl; + stream << padding << "" << std::endl; + stream << padding << " /* move all events but last over and remember the last one */" << std::endl; + stream << padding << " _iwdIdx1 = 0;" << std::endl; + stream << padding << " _iwdQLength = len(queue) - 1;" << std::endl; + stream << padding << "" << std::endl; + stream << padding << " do" << std::endl; + stream << padding << " :: _iwdIdx1 < _iwdQLength -> {" << std::endl; + stream << padding << " queue?_iwdTmpE;" << std::endl; + stream << padding << " _iwdQ[_iwdIdx1].name = _iwdTmpE.name;" << std::endl; + + stream << _analyzer->getTypeAssignment("_iwdQ[_iwdIdx1]", "_iwdTmpE", _analyzer->getType("_event"), padding + " "); + + stream << padding << " _iwdIdx1++;" << std::endl; + stream << padding << " }" << std::endl; + stream << padding << " :: else -> break;" << std::endl; + stream << padding << " od" << std::endl; + stream << padding << "" << std::endl; + stream << padding << " queue?_iwdLastE;" << std::endl; + stream << padding << "" << std::endl; + stream << padding << " /* _iwdQ now contains all but last item in _iwdLastE */" << std::endl; + stream << padding << " assert(len(queue) == 0);" << std::endl; + stream << padding << "" << std::endl; + stream << padding << " /* reinsert into queue and place _iwdLastE correctly */" << std::endl; + stream << padding << " _iwdInserted = false;" << std::endl; + stream << padding << " _iwdIdx2 = 0;" << std::endl; + stream << padding << "" << std::endl; + stream << padding << " do" << std::endl; + stream << padding << " :: _iwdIdx2 < _iwdIdx1 -> {" << std::endl; + stream << padding << " _iwdTmpE.name = _iwdQ[_iwdIdx2].name;" << std::endl; + + stream << _analyzer->getTypeAssignment("_iwdTmpE", "_iwdQ[_iwdIdx2]", _analyzer->getType("_event"), padding + " "); + + stream << padding << "" << std::endl; + stream << padding << " if" << std::endl; + stream << padding << " :: _iwdTmpE.delay > _iwdLastE.delay -> {" << std::endl; + stream << padding << " queue!_iwdLastE;" << std::endl; + stream << padding << " _iwdInserted = true;" << std::endl; + stream << padding << " }" << std::endl; + stream << padding << " :: else -> skip" << std::endl; + stream << padding << " fi;" << std::endl; + stream << padding << "" << std::endl; + stream << padding << " queue!_iwdTmpE;" << std::endl; + stream << padding << " _iwdIdx2++;" << std::endl; + stream << padding << " }" << std::endl; + stream << padding << " :: else -> break;" << std::endl; + stream << padding << " od" << std::endl; + stream << padding << "" << std::endl; + stream << padding << " if" << std::endl; + stream << padding << " :: !_iwdInserted -> queue!_iwdLastE;" << std::endl; + stream << padding << " :: else -> skip;" << std::endl; + stream << padding << " fi;" << std::endl; + stream << padding << "" << std::endl; + stream << padding << " }" << std::endl; + stream << padding << " :: else -> skip;" << std::endl; + stream << padding << " fi;" << std::endl; + stream << padding << " }" << std::endl; + stream << padding << "}" << std::endl; } void ChartToPromela::writeAdvanceTime(std::ostream& stream, int indent) { @@ -2653,7 +2653,7 @@ void ChartToPromela::writeAdvanceTime(std::ostream& stream, int indent) { for (int i = 0; i < indent; i++) { padding += " "; } - + stream << padding << "inline advanceTime(increment, queue) {" << std::endl; stream << padding << " tmpIndex = 0;" << std::endl; stream << padding << " do" << std::endl; @@ -2676,7 +2676,7 @@ void ChartToPromela::writeRemovePendingEventsFromInvoker(std::ostream& stream, i queues.push_back("eQ"); if (_allowEventInterleaving) queues.push_back("tmpQ"); - + stream << "inline removePendingEventsForInvoker(invokeIdentifier) {" << std::endl; for (std::map<Arabica::DOM::Node<std::string>, ChartToPromela*>::iterator queueIter = _machinesAll->begin(); queueIter != _machinesAll->end(); queueIter++) { for (std::list<std::string>::iterator qIter = queues.begin(); qIter != queues.end(); qIter++) { @@ -2741,42 +2741,42 @@ void ChartToPromela::writeScheduleMachines(std::ostream& stream, int indent) { for (int i = 0; i < indent; i++) { padding += " "; } - + stream << padding << "inline scheduleMachines() {" << std::endl; std::list<std::string> queues; queues.push_back("eQ"); if (_allowEventInterleaving) queues.push_back("tmpQ"); - + stream << " /* schedule state-machines with regard to their event's delay */" << std::endl; stream << " skip;" << std::endl; stream << " d_step {" << std::endl; - + stream << std::endl << "/* determine smallest delay */" << std::endl; stream << " int smallestDelay = 2147483647;" << std::endl; - + for (std::map<Arabica::DOM::Node<std::string>, ChartToPromela*>::iterator queueIter = _machinesAll->begin(); queueIter != _machinesAll->end(); queueIter++) { for (std::list<std::string>::iterator qIter = queues.begin(); qIter != queues.end(); qIter++) { stream << " determineSmallestDelay(smallestDelay, " << queueIter->second->_prefix << *qIter << ");" << std::endl; } } // stream << " printf(\"======= Lowest delay is %d\\n\", smallestDelay);" << std::endl; - + stream << std::endl << "/* prioritize processes with lowest delay or internal events */" << std::endl; - + for (std::map<Arabica::DOM::Node<std::string>, ChartToPromela*>::iterator queueIter = _machinesAll->begin(); queueIter != _machinesAll->end(); queueIter++) { stream << " rescheduleProcess(smallestDelay, " - << queueIter->second->_prefix << "procid, " - << queueIter->second->_prefix << "iQ, " - << queueIter->second->_prefix << "eQ"; + << queueIter->second->_prefix << "procid, " + << queueIter->second->_prefix << "iQ, " + << queueIter->second->_prefix << "eQ"; if (_allowEventInterleaving) { stream << ", " << queueIter->second->_prefix << "tmpQ);" << std::endl; } else { stream << ");" << std::endl; } } - + stream << std::endl << "/* advance time by subtracting the smallest delay from all event delays */" << std::endl; stream << " if" << std::endl; stream << " :: (smallestDelay > 0) -> {" << std::endl; @@ -2792,13 +2792,13 @@ void ChartToPromela::writeScheduleMachines(std::ostream& stream, int indent) { stream << " set_priority(_pid, 10);" << std::endl << std::endl; stream << padding << "}" << std::endl; } - + void ChartToPromela::writeEventDispatching(std::ostream& stream) { for (std::map<std::string, GlobalState*>::iterator stateIter = _activeConf.begin(); stateIter != _activeConf.end(); stateIter++) { - + const std::string& stateId = stateIter->first; const GlobalState* state = stateIter->second; - + stream << std::endl << "/* ### current state "; FlatStateIdentifier flatActiveSource(stateId); PRETTY_PRINT_LIST(stream, flatActiveSource.getActive()); @@ -2810,7 +2810,7 @@ void ChartToPromela::writeEventDispatching(std::ostream& stream) { stream << " }" << std::endl; } } - + void ChartToPromela::writeDispatchingBlock(std::ostream& stream, std::list<GlobalTransition*> transitions, int indent) { std::string padding; for (int i = 0; i < indent; i++) { @@ -2840,7 +2840,7 @@ void ChartToPromela::writeDispatchingBlock(std::ostream& stream, std::list<Globa stream << _prefix << "spontaneous"; } else { std::string eventDescs = currTrans->eventDesc; - + std::list<std::string> eventNames = tokenizeIdRefs(eventDescs); std::set<std::string> eventPrefixes; std::list<std::string>::iterator eventNameIter = eventNames.begin(); @@ -2868,7 +2868,7 @@ void ChartToPromela::writeDispatchingBlock(std::ostream& stream, std::list<Globa if (eventPrefixes.size() > 1) stream << " ("; - + std::string seperator; std::set<std::string>::iterator eventIter = eventPrefixes.begin(); while(eventIter != eventPrefixes.end()) { @@ -2892,37 +2892,37 @@ void ChartToPromela::writeDispatchingBlock(std::ostream& stream, std::list<Globa } if (currTrans->hasExecutableContent || currTrans->historyTrans.size() > 0) { stream << " -> { " << std::endl; - if (!envVarIsTrue("USCXML_ANNOTATE_NOCOMMENT")) { - stream << "/* transition to "; - FlatStateIdentifier flatActiveSource(currTrans->activeDestination); - PRETTY_PRINT_LIST(stream, flatActiveSource.getActive()); - stream << " */" << std::endl; - } - + if (!envVarIsTrue("USCXML_ANNOTATE_NOCOMMENT")) { + stream << "/* transition to "; + FlatStateIdentifier flatActiveSource(currTrans->activeDestination); + PRETTY_PRINT_LIST(stream, flatActiveSource.getActive()); + stream << " */" << std::endl; + } + if (_traceTransitions) { for (std::set<int>::iterator transRefIter = currTrans->transitionRefs.begin(); transRefIter != currTrans->transitionRefs.end(); transRefIter++) { stream << padding << " " << _prefix << "transitions[" << *transRefIter << "] = true; " << std::endl; } } - + stream << padding << " goto " << _prefix << "t" << currTrans->index << ";" << std::endl; stream << padding << "}" << std::endl; } else { - + stream << " -> {" << std::endl; GlobalState* newState = _activeConf[currTrans->activeDestination]; assert(newState != NULL); - if (!envVarIsTrue("USCXML_ANNOTATE_NOCOMMENT")) { - stream << "/* new state "; - FlatStateIdentifier flatActiveDest(currTrans->activeDestination); - PRETTY_PRINT_LIST(stream, flatActiveDest.getActive()); - stream << " */" << std::endl; - } + if (!envVarIsTrue("USCXML_ANNOTATE_NOCOMMENT")) { + stream << "/* new state "; + FlatStateIdentifier flatActiveDest(currTrans->activeDestination); + PRETTY_PRINT_LIST(stream, flatActiveDest.getActive()); + stream << " */" << std::endl; + } stream << padding << " " << _prefix << "s = s" << newState->activeIndex << ";" << std::endl; - TRANSITION_TRACE(currTrans, false); + TRANSITION_TRACE(currTrans, false); writeTransitionClosure(stream, currTrans, newState, indent + 1); stream << padding << "}" << std::endl; } @@ -2947,7 +2947,7 @@ void ChartToPromela::writeMain(std::ostream& stream) { } stream << std::endl; } - + stream << " run " << (_prefix.size() == 0 ? "machine_" : _prefix) << "run() priority 10;" << std::endl; stream << "}" << std::endl; @@ -2958,18 +2958,18 @@ void ChartToPromela::initNodes() { // some things we share with our invokers if (_analyzer == NULL) _analyzer = new PromelaCodeAnalyzer(); - + if (_machinesAll == NULL) { _machinesAll = new std::map<Arabica::DOM::Node<std::string>, ChartToPromela*>(); (*_machinesAll)[_scxml] = this; } - + if (_machinesAllPerId == NULL) _machinesAllPerId = new std::map<std::string, Arabica::DOM::Node<std::string> >(); if (_parentTopMost == NULL) _parentTopMost = this; - + _internalQueueLength = getMinInternalQueueLength(MSG_QUEUE_LENGTH); _externalQueueLength = getMinExternalQueueLength(MSG_QUEUE_LENGTH); @@ -2984,7 +2984,7 @@ void ChartToPromela::initNodes() { _analyzer->addEvent("done.state." + ATTR(stateElem, "id")); } } - + { // shorten UUID ids at invokers for readability NodeSet<std::string> invokes = filterChildElements(_nsInfo.xmlNSPrefix + "invoke", _scxml, true); @@ -3003,18 +3003,18 @@ void ChartToPromela::initNodes() { } } - + // are there nestes SCXML invokers? { NodeSet<std::string> invokes = filterChildElements(_nsInfo.xmlNSPrefix + "invoke", _scxml, true); for (int i = 0; i < invokes.size(); i++) { if (!HAS_ATTR_CAST(invokes[i], "type") || - ATTR_CAST(invokes[i], "type") == "scxml" || - ATTR_CAST(invokes[i], "type") == "http://www.w3.org/TR/scxml/#SCXMLEventProcessor" || - ATTR_CAST(invokes[i], "type") == "http://www.w3.org/TR/scxml/") { + ATTR_CAST(invokes[i], "type") == "scxml" || + ATTR_CAST(invokes[i], "type") == "http://www.w3.org/TR/scxml/#SCXMLEventProcessor" || + ATTR_CAST(invokes[i], "type") == "http://www.w3.org/TR/scxml/") { assert(HAS_ATTR_CAST(invokes[i], "id")); Element<std::string>(invokes[i]).setAttribute("name", ATTR_CAST(invokes[i], "id")); - + _prefix = "MAIN_"; Interpreter nested; if (HAS_ATTR_CAST(invokes[i], "src")) { @@ -3032,12 +3032,12 @@ void ChartToPromela::initNodes() { Document<std::string> nestedDoc = domFactory.createDocument(_scxml.getOwnerDocument().getNamespaceURI(), "", 0); Node<std::string> importRoot = nestedDoc.importNode(nestedRoot[0], true); nestedDoc.appendChild(importRoot); - + nested = Interpreter::fromDOM(nestedDoc, _nsInfo, _sourceURL); } - + // std::cout << invokes[i] << std::endl; - + // we found machines but have no prefix if (_prefix.length() == 0) _prefix = "MAIN_"; @@ -3048,13 +3048,13 @@ void ChartToPromela::initNodes() { _machines[invokes[i]]->_parentTopMost = _parentTopMost; _machines[invokes[i]]->_machinesAll = _machinesAll; (*_machinesAll)[invokes[i]] = _machines[invokes[i]]; - + _machines[invokes[i]]->_invokerid = ATTR_CAST(invokes[i], "id"); _machines[invokes[i]]->_prefix = ATTR_CAST(invokes[i], "id") + "_"; - + _analyzer->addLiteral(_machines[invokes[i]]->_invokerid); _analyzer->addEvent("done.invoke." + _machines[invokes[i]]->_invokerid); - + _machinesPerId[ATTR_CAST(invokes[i], "id")] = invokes[i]; (*_machinesAllPerId)[ATTR_CAST(invokes[i], "id")] = invokes[i]; } @@ -3064,7 +3064,7 @@ void ChartToPromela::initNodes() { if (_machines.size() > 0) { _analyzer->addCode("_event.invokeid", this); } - + // gather all potential members per history std::map<std::string, Arabica::DOM::Element<std::string> >::iterator histIter = _historyTargets.begin(); while(histIter != _historyTargets.end()) { @@ -3079,7 +3079,7 @@ void ChartToPromela::initNodes() { } histIter++; } - + // initialize event trie with all events that might occur NodeSet<std::string> internalEventNames; internalEventNames.push_back(_xpath.evaluate("//" + _nsInfo.xpathPrefix + "transition", _scxml).asNodeSet()); @@ -3105,7 +3105,7 @@ void ChartToPromela::initNodes() { // _analyzer->addCode("bumpDownArrow = 1; _event.foo = 3; forgetSelectedServer = 1;", this); // exit(0); - + // transform data / assign json into PROMELA statements { NodeSet<std::string> asgn; @@ -3115,19 +3115,19 @@ void ChartToPromela::initNodes() { for (int i = 0; i < asgn.size(); i++) { if (isInEmbeddedDocument(asgn[i])) continue; - + Element<std::string> asgnElem(asgn[i]); - + std::string key; if (HAS_ATTR(asgnElem, "id")) { key = ATTR(asgnElem, "id"); } else if (HAS_ATTR(asgnElem, "location")) { key = ATTR(asgnElem, "location"); } - + if (key.length() == 0) continue; - + std::string value; if (HAS_ATTR(asgnElem, "expr")) { value = ATTR(asgnElem, "expr"); @@ -3143,15 +3143,15 @@ void ChartToPromela::initNodes() { } } } - + boost::trim(value); if (value.size() == 0) continue; - + // remove all children, we will replae by suitable promela statements while(asgnElem.hasChildNodes()) asgnElem.removeChild(asgnElem.getFirstChild()); - + std::string newValue; Data json = Data::fromJSON(value); if (!json.empty()) { @@ -3161,24 +3161,24 @@ void ChartToPromela::initNodes() { } newValue = sanitizeCode(newValue); _analyzer->addCode(newValue, this); - + if (asgnElem.getLocalName() == "data") _varInitializers.push_back(newValue); Text<std::string> newText = _document.createTextNode(newValue); asgnElem.insertBefore(newText, Node<std::string>()); } } - + // do we need sendid / invokeid? { NodeSet<std::string> invokes = filterChildElements(_nsInfo.xmlNSPrefix + "invoke", _scxml, true); NodeSet<std::string> sends = filterChildElements(_nsInfo.xmlNSPrefix + "send", _scxml, true); NodeSet<std::string> cancels = filterChildElements(_nsInfo.xmlNSPrefix + "cancel", _scxml, true); - + if (cancels.size() > 0) { _analyzer->addCode("_event.invokeid", this); } - + for (int i = 0; i < sends.size(); i++) { if (HAS_ATTR_CAST(sends[i], "idlocation")) { _analyzer->addCode("_event.sendid", this); @@ -3195,12 +3195,12 @@ void ChartToPromela::initNodes() { _analyzer->addCode("_event.delay", this); #if NEW_DELAY_RESHUFFLE #else - _analyzer->addCode("_event.seqNr", this); + _analyzer->addCode("_event.seqNr", this); #endif } } } - + { // string literals for raise / send content NodeSet<std::string> withContent; @@ -3217,30 +3217,30 @@ void ChartToPromela::initNodes() { } } } - + { // gather all inline promela comments pmlInlines = PromelaInlines(_scxml); if (pmlInlines.getAllOfType(PromelaInline::PROMELA_EVENT_ONLY).size() > 0) _analyzer->addCode("_x.states", this); - + // register events and string literals for (std::list<PromelaInline*>::iterator inlIter = pmlInlines.allInlines.begin(); inlIter != pmlInlines.allInlines.end(); inlIter++) { if ((*inlIter)->type != (PromelaInline::PROMELA_EVENT_ONLY)) continue; - + Data json = Data::fromJSON((*inlIter)->content); if (!json.empty()) { std::list<std::string> eventNames = PromelaInlines::getEventNames(json); for (std::list<std::string>::iterator evIter = eventNames.begin(); evIter != eventNames.end(); evIter++) { _analyzer->addEvent(*evIter); } - + std::list<std::string> stringLiterals = PromelaInlines::getStringLiterals(json); for (std::list<std::string>::iterator strIter = stringLiterals.begin(); strIter != stringLiterals.end(); strIter++) { _analyzer->addLiteral(*strIter); } - + if (json.array.size() > 0) { for (int i = 0; i < json.array.size(); i++) { std::string expr = dataToAssignments("_event", json.item(i)); @@ -3249,7 +3249,7 @@ void ChartToPromela::initNodes() { } else { std::string expr = dataToAssignments("_event", json); _analyzer->addCode(expr, this); - + } } @@ -3449,7 +3449,7 @@ 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; @@ -3470,7 +3470,7 @@ void ChartToPromela::writeProgram(std::ostream& stream) { stream << std::endl; initNodes(); - + for (std::map<Arabica::DOM::Node<std::string>, ChartToPromela*>::iterator nestedIter = _machines.begin(); nestedIter != _machines.end(); nestedIter++) { if (nestedIter->second->_start == NULL) { nestedIter->second->interpret(); @@ -3504,23 +3504,23 @@ void ChartToPromela::writeProgram(std::ostream& stream) { 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 (_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; - } + if (_analyzer->usesEventField("delay")) { + writeInsertWithDelay(stream); + stream << std::endl; + } #endif - + if (_analyzer->usesEventField("delay") && _machines.size() > 0) { - writeDetermineShortestDelay(stream); + writeDetermineShortestDelay(stream); stream << std::endl; writeAdvanceTime(stream); stream << std::endl; @@ -3557,11 +3557,11 @@ void ChartToPromela::writeProgram(std::ostream& stream) { nestedIter->second->writeFSM(stream); stream << std::endl; } - + // write ltl expression for success std::stringstream acceptingStates; std::string seperator; - + for (std::map<std::string, GlobalState*>::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()) { diff --git a/src/uscxml/transform/ChartToPromela.h b/src/uscxml/transform/ChartToPromela.h index 9c3c99b..d289436 100644 --- a/src/uscxml/transform/ChartToPromela.h +++ b/src/uscxml/transform/ChartToPromela.h @@ -52,7 +52,7 @@ public: PromelaInline(const Arabica::DOM::Node<std::string>& node); virtual ~PromelaInline() {} - + operator bool() { return (type != PROMELA_NIL); } @@ -60,13 +60,13 @@ public: std::list<PromelaInline*> children; PromelaInline* prevSibling; PromelaInline* nextSibling; - + virtual void dump(); virtual bool relatesTo(const Arabica::DOM::Node<std::string>& node) { return container == node; } - + size_t level; std::string content; Arabica::DOM::Element<std::string> container; @@ -78,22 +78,22 @@ protected: class USCXML_API PromelaInlines { public: - + PromelaInlines(const Arabica::DOM::Node<std::string>& node); PromelaInlines() {} virtual ~PromelaInlines(); - + std::list<PromelaInline*> getRelatedTo(const Arabica::DOM::Node<std::string>& node, PromelaInline::PromelaInlineType type); std::list<PromelaInline*> getAllOfType(uint32_t type); std::map<Arabica::DOM::Node<std::string>, std::list<PromelaInline*> > inlines; std::list<PromelaInline*> allInlines; - + static std::list<std::string> getStringLiterals(const Data& data); static std::list<std::string> getEventNames(const Data& data); - + }; class USCXML_API PromelaEventSource : public PromelaInline { @@ -104,7 +104,7 @@ public: content = pmlInline.content; events = Data::fromJSON(pmlInline.content); } - + virtual bool relatesTo(const Arabica::DOM::Node<std::string>& node) { return container == node || InterpreterImpl::isDescendant(node, container); } @@ -128,30 +128,30 @@ public: class USCXML_API PromelaEventSource { public: - + enum PromelaEventSourceType { PROMELA_EVENT_SOURCE_INVALID, PROMELA_EVENT_SOURCE_INVOKER, PROMELA_EVENT_SOURCE_GLOBAL, }; - + PromelaEventSource(); PromelaEventSource(const PromelaInline& source, PromelaCodeAnalyzer* analyzer = NULL, uint32_t externalQueueLength = 0); - + void writeStart(std::ostream& stream, int indent = 0); void writeStop(std::ostream& stream, int indent = 0); void writeDeclarations(std::ostream& stream, int indent = 0); void writeBody(std::ostream& stream); - + operator bool() { return type != PROMELA_EVENT_SOURCE_INVALID; } - + PromelaInline source; std::string name; uint32_t externalQueueLength; uint32_t longestSequence; - + Arabica::DOM::Node<std::string> container; std::list<std::list<std::string> > sequences; PromelaEventSourceType type; @@ -159,7 +159,7 @@ public: }; #endif - + class USCXML_API PromelaCodeAnalyzer { public: class PromelaTypedef { @@ -172,7 +172,7 @@ public: size_t maxValue; std::map<std::string, PromelaTypedef> types; std::set<ChartToPromela*> occurrences; - + bool operator==(const PromelaTypedef& other) const { return name == other.name; } @@ -199,15 +199,15 @@ public: 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()) + _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 = ""); - + 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; } @@ -251,9 +251,9 @@ public: return _typeDefs; } - PromelaTypedef& getType(const std::string& typeName) { - return _typeDefs.types.at(typeName); - } + PromelaTypedef& getType(const std::string& typeName) { + return _typeDefs.types.at(typeName); + } protected: std::string createMacroName(const std::string& literal); @@ -266,7 +266,7 @@ protected: std::map<std::string, int> _states; std::map<std::string, int> _events; - + PromelaTypedef _typeDefs; Trie _eventTrie; @@ -288,12 +288,12 @@ public: }; ExecContentSeqItem(ExecContentType type, const std::set<GlobalTransition*>& transitions, const GlobalTransition::Action& action) - : type(type), transitions(transitions), action(action) {} + : type(type), transitions(transitions), action(action) {} ExecContentSeqItem(ExecContentType type, GlobalTransition* transition, const GlobalTransition::Action& action) - : type(type), action(action) { + : type(type), action(action) { transitions.insert(transition); } - + ExecContentType type; std::set<GlobalTransition*> transitions; GlobalTransition::Action action; @@ -303,48 +303,48 @@ class HistoryTransitionClass { public: HistoryTransitionClass(GlobalTransition* transition); HistoryTransitionClass(const std::string& from, const std::string& to); - + void init(const std::string& from, const std::string& to); - + std::map<std::string, std::set<std::string> > toRemember; std::map<std::string, std::set<std::string> > toKeep; std::map<std::string, std::set<std::string> > toForget; - + std::set<GlobalTransition*> members; void merge(const HistoryTransitionClass& other); bool matches(const HistoryTransitionClass& other); }; - + class USCXML_API ChartToPromela : public TransformerImpl, public ChartToFSM { public: virtual ~ChartToPromela(); static Transformer transform(const Interpreter& other); - + void writeTo(std::ostream& stream); - + protected: ChartToPromela(const Interpreter& other) - : TransformerImpl(), - ChartToFSM(other), - _analyzer(NULL), - _allowEventInterleaving(false), - _hasIndexLessLoops(false), - _writeTransitionPrintfs(false), - _traceTransitions(false), - _machinesAll(NULL), - _parent(NULL), - _parentTopMost(NULL), - _machinesAllPerId(NULL), - _perfTransProcessed(0), - _perfTransTotal(0), - _perfHistoryProcessed(0), - _perfHistoryTotal(0), - _perfStatesProcessed(0), - _perfStatesTotal(0), - _lastTimeStamp(0) {} + : TransformerImpl(), + ChartToFSM(other), + _analyzer(NULL), + _allowEventInterleaving(false), + _hasIndexLessLoops(false), + _writeTransitionPrintfs(false), + _traceTransitions(false), + _machinesAll(NULL), + _parent(NULL), + _parentTopMost(NULL), + _machinesAllPerId(NULL), + _perfTransProcessed(0), + _perfTransTotal(0), + _perfHistoryProcessed(0), + _perfHistoryTotal(0), + _perfStatesProcessed(0), + _perfStatesTotal(0), + _lastTimeStamp(0) {} void initNodes(); @@ -377,10 +377,10 @@ protected: void writeStartInvoker(std::ostream& stream, const Arabica::DOM::Node<std::string>& node, ChartToPromela* invoker, int indent = 0); //void writeRemovePendingEventsFromInvoker(std::ostream& stream, ChartToPromela* invoker, int indent = 0, bool atomic = true); - + void writeDetermineShortestDelay(std::ostream& stream, int indent = 0); - void writeInsertWithDelay(std::ostream& stream, int indent = 0); - void writeAdvanceTime(std::ostream& stream, int indent = 0); + void writeInsertWithDelay(std::ostream& stream, int indent = 0); + void writeAdvanceTime(std::ostream& stream, int indent = 0); void writeRescheduleProcess(std::ostream& stream, int indent = 0); void writeScheduleMachines(std::ostream& stream, int indent = 0); void writeCancelEvents(std::ostream& stream, int indent = 0); @@ -388,7 +388,7 @@ protected: std::list<GlobalTransition::Action> getTransientContent(GlobalTransition* transition); //Arabica::DOM::Node<std::string> getUltimateTarget(const Arabica::DOM::Element<std::string>& transition); - + static std::string declForRange(const std::string& identifier, long minValue, long maxValue, bool nativeOnly = false); static std::string conditionForHistoryTransition(const GlobalTransition* transition); @@ -396,7 +396,7 @@ protected: std::string sanitizeCode(const std::string& code); std::string dataToAssignments(const std::string& prefix, const Data& data); - + // Arabica::XPath::NodeSet<std::string> _globalStates; // Arabica::DOM::Node<std::string> _startState; // std::map<std::string, Arabica::DOM::Element<std::string> > _states; @@ -409,28 +409,28 @@ protected: bool _hasIndexLessLoops; bool _writeTransitionPrintfs; bool _traceTransitions; - + uint32_t _externalQueueLength; uint32_t _internalQueueLength; - + PromelaInlines pmlInlines; // std::map<std::string, PromelaEventSource> _invokers; // PromelaEventSource _globalEventSource; - + std::map<std::string, std::map<std::string, size_t> > _historyMembers; // ids of all history states std::set<std::string> _dataModelVars; - + Arabica::DOM::Node<std::string> _finalize; std::map<Arabica::DOM::Node<std::string>, ChartToPromela*> _machines; std::map<Arabica::DOM::Node<std::string>, ChartToPromela*>* _machinesAll; ChartToPromela* _parent; // our invoking interpreter ChartToPromela* _parentTopMost; - + std::map<std::string, Arabica::DOM::Node<std::string> > _machinesPerId; std::map<std::string, Arabica::DOM::Node<std::string> >* _machinesAllPerId; std::string _prefix; // our prefix in case of nested SCXML documents std::string _invokerid; - + uint64_t _perfTransProcessed; uint64_t _perfTransTotal; uint64_t _perfHistoryProcessed; diff --git a/src/uscxml/transform/ChartToTex.cpp b/src/uscxml/transform/ChartToTex.cpp index 35731a1..f38740a 100644 --- a/src/uscxml/transform/ChartToTex.cpp +++ b/src/uscxml/transform/ChartToTex.cpp @@ -53,12 +53,12 @@ void ChartToTex::writeTex(std::ostream& stream) { bool wroteRowStart = false; std::string seperator; - + for (std::map<std::string, GlobalState*>::iterator stateIter = _globalConf.begin(); stateIter != _globalConf.end(); stateIter++) { assert(_indexToState.find(stateIter->second->index) == _indexToState.end()); _indexToState[stateIter->second->index] = stateIter->second; } - + stream << "% " << _sourceURL.asString() << std::endl; stream << "%<*provideCommand>" << std::endl; @@ -84,7 +84,7 @@ void ChartToTex::writeTex(std::ostream& stream) { stream << "%<*tableRows>" << std::endl; wroteRowStart = true; } - + stream << "%<*globalState" << currState->index << ">" << std::endl; // state index @@ -95,15 +95,15 @@ void ChartToTex::writeTex(std::ostream& stream) { stream << "\\globalStateListCell[t]{"; stream << "\\tikzmark{active_" << currState->index << "}"; stream << "$\\widetilde{s}_a(" << currState->index << ")$: " << stateListToTex(flatId.getFlatActive(), flatId.getActive().size() == 0) << "\\\\"; - + // already visited states stream << "\\tikzmark{visited_" << currState->index << "}"; stream << "$\\widetilde{s}_d(" << currState->index << ")$: " << stateListToTex(flatId.getFlatVisited(), flatId.getVisited().size() == 0) << "\\\\"; - + // history assignments stream << "\\tikzmark{history_" << currState->index << "}"; stream << "$\\widetilde{s}_h(" << currState->index << ")$: " << stateListToTex(flatId.getFlatHistory(), flatId.getHistory().size() == 0) << "} & "; - + // all transitions std::set<std::string> origTransitions; for (std::list<GlobalTransition*>::iterator transIter = stateIter->second->sortedOutgoing.begin(); transIter != stateIter->second->sortedOutgoing.end(); transIter++) { @@ -118,7 +118,7 @@ void ChartToTex::writeTex(std::ostream& stream) { } } } - + if (origTransitions.size() > 0) { stream << "$\\{ "; seperator = ""; @@ -144,7 +144,7 @@ void ChartToTex::writeTex(std::ostream& stream) { if (!currTrans->isValid) stream << "\\sout{"; - + Arabica::XPath::NodeSet<std::string> members = currTrans->getTransitions(); if (members.size() > 0) { stream << "$\\{ "; @@ -162,28 +162,35 @@ void ChartToTex::writeTex(std::ostream& stream) { } else { stream << "$\\emptyset$"; } - // stream << "& \\sout{$\\{ t_2, t_0 \\}$}, & \\emph{$Inv_4$: nested source states} \\\\" << std::endl; - // stream << "& $\\{ t_2 \\}$ & & $\\widetilde{s}(2)$ \\\\" << std::endl; - // stream << "& $\\{ t_0 \\}$ & & $\\widetilde{s}(4)$ \\\\" << std::endl; + // stream << "& \\sout{$\\{ t_2, t_0 \\}$}, & \\emph{$Inv_4$: nested source states} \\\\" << std::endl; + // stream << "& $\\{ t_2 \\}$ & & $\\widetilde{s}(2)$ \\\\" << std::endl; + // stream << "& $\\{ t_0 \\}$ & & $\\widetilde{s}(4)$ \\\\" << std::endl; if (!currTrans->isValid) { #if 1 stream << " } & \\emph{"; switch(currTrans->invalidReason) { - case GlobalTransition::NO_COMMON_EVENT: - stream << "$Inv_1$: "; break; - case GlobalTransition::MIXES_EVENT_SPONTANEOUS: - stream << "$Inv_2$: "; break; - case GlobalTransition::SAME_SOURCE_STATE: - stream << "$Inv_3$: "; break; - case GlobalTransition::CHILD_ENABLED: - stream << "$Inv_4$: "; break; - case GlobalTransition::PREEMPTING_MEMBERS: - stream << "$Inv_5$: "; break; - case GlobalTransition::UNCONDITIONAL_MATCH: - stream << "$Opt_1$: "; break; - case GlobalTransition::UNCONDITIONAL_SUPERSET: - stream << "$Opt_2$: "; break; + case GlobalTransition::NO_COMMON_EVENT: + stream << "$Inv_1$: "; + break; + case GlobalTransition::MIXES_EVENT_SPONTANEOUS: + stream << "$Inv_2$: "; + break; + case GlobalTransition::SAME_SOURCE_STATE: + stream << "$Inv_3$: "; + break; + case GlobalTransition::CHILD_ENABLED: + stream << "$Inv_4$: "; + break; + case GlobalTransition::PREEMPTING_MEMBERS: + stream << "$Inv_5$: "; + break; + case GlobalTransition::UNCONDITIONAL_MATCH: + stream << "$Opt_1$: "; + break; + case GlobalTransition::UNCONDITIONAL_SUPERSET: + stream << "$Opt_2$: "; + break; } stream << currTrans->invalidMsg << "} "; #endif @@ -192,7 +199,7 @@ void ChartToTex::writeTex(std::ostream& stream) { } else { stream << " & "; std::stringstream execContentSS; - + seperator = ""; for (std::list<GlobalTransition::Action>::iterator actionIter = currTrans->actions.begin(); actionIter != currTrans->actions.end(); actionIter++) { Element<std::string> execContent; @@ -224,7 +231,7 @@ void ChartToTex::writeTex(std::ostream& stream) { seperator = ", "; } } - + if (execContentSS.str().size() > 0) { stream << "$\\mathcal{X} := (" << execContentSS.str() << ")$"; } else { @@ -241,7 +248,7 @@ void ChartToTex::writeTex(std::ostream& stream) { if (stateIter->second->sortedOutgoing.size() == 0) { stream << " & & & \\\\" << std::endl; } - + stream << "\\hline" << std::endl; } stream << "%</globalState" << currState->index << ">" << std::endl; @@ -270,7 +277,7 @@ std::string ChartToTex::stateListToTex(const std::string& input, bool isEmpty) { } return statesTex; } - + std::string ChartToTex::texEscape(const std::string& input) { std::string texString(input); boost::replace_all(texString, "\\", "\\\\"); diff --git a/src/uscxml/transform/ChartToTex.h b/src/uscxml/transform/ChartToTex.h index b7542f4..037b55c 100644 --- a/src/uscxml/transform/ChartToTex.h +++ b/src/uscxml/transform/ChartToTex.h @@ -39,18 +39,18 @@ public: virtual ~ChartToTex(); static Transformer transform(const Interpreter& other); - + void writeTo(std::ostream& stream); - + protected: ChartToTex(const Interpreter& other) - : TransformerImpl(), - ChartToFSM(other) {} + : TransformerImpl(), + ChartToFSM(other) {} void writeTex(std::ostream& stream); std::map<unsigned long, GlobalState*> _indexToState; - + private: static std::string stateListToTex(const std::string& input, bool isEmpty); static std::string texEscape(const std::string& input); diff --git a/src/uscxml/transform/FlatStateIdentifier.h b/src/uscxml/transform/FlatStateIdentifier.h index f082b18..4afd956 100644 --- a/src/uscxml/transform/FlatStateIdentifier.h +++ b/src/uscxml/transform/FlatStateIdentifier.h @@ -93,8 +93,8 @@ public: } static std::string toStateId(const Arabica::XPath::NodeSet<std::string> activeStates, - const Arabica::XPath::NodeSet<std::string> alreadyEnteredStates = Arabica::XPath::NodeSet<std::string>(), - const std::map<std::string, Arabica::XPath::NodeSet<std::string> > historyStates = std::map<std::string, Arabica::XPath::NodeSet<std::string> >()) { + const Arabica::XPath::NodeSet<std::string> alreadyEnteredStates = Arabica::XPath::NodeSet<std::string>(), + const std::map<std::string, Arabica::XPath::NodeSet<std::string> > historyStates = std::map<std::string, Arabica::XPath::NodeSet<std::string> >()) { FlatStateIdentifier tmp(activeStates, alreadyEnteredStates, historyStates); return tmp.getStateId(); } diff --git a/src/uscxml/transform/Transformer.h b/src/uscxml/transform/Transformer.h index 9d31b71..16d0a94 100644 --- a/src/uscxml/transform/Transformer.h +++ b/src/uscxml/transform/Transformer.h @@ -39,12 +39,12 @@ public: class USCXML_API Transformer : public boost::enable_shared_from_this<Transformer> { public: // Transformer(const Interpreter& source) { _impl = new (source) } - + Transformer() : _impl() {} // the empty, invalid interpreter Transformer(boost::shared_ptr<TransformerImpl> const impl) : _impl(impl) { } Transformer(const Transformer& other) : _impl(other._impl) { } virtual ~Transformer() {}; - + operator bool() const { return (_impl); } @@ -68,11 +68,11 @@ public: operator Interpreter() { return _impl->operator Interpreter(); } - - boost::shared_ptr<TransformerImpl> getImpl() { - return _impl; - } - + + boost::shared_ptr<TransformerImpl> getImpl() { + return _impl; + } + protected: boost::shared_ptr<TransformerImpl> _impl; diff --git a/test/src/test-c-machine.cpp b/test/src/test-c-machine.cpp index ae967ad..390ca0a 100644 --- a/test/src/test-c-machine.cpp +++ b/test/src/test-c-machine.cpp @@ -40,619 +40,621 @@ using namespace uscxml; typedef struct scxml_foreach_info scxml_foreach_info; struct scxml_foreach_info { - size_t iterations; - size_t currIteration; + size_t iterations; + size_t currIteration; }; class GenCInterpreterInfo : public InterpreterInfo { public: - NameSpaceInfo getNameSpaceInfo() const { - return nsInfo; - } - const std::string& getName() { - return name; - } - const std::string& getSessionId() { - return sessionId; - } - const std::map<std::string, IOProcessor>& getIOProcessors() { - return ioProcs; - } - bool isInState(const std::string& stateId) { - for (int i = 0 ; i < SCXML_NUMBER_STATES; i++) { - if (scxml_states[i].name != NULL && IS_SET(i, ctx->config) && stateId == scxml_states[i].name) - return true; - } - return false; - } - Arabica::DOM::Document<std::string> getDocument() const { - return document; - } - const std::map<std::string, Invoker>& getInvokers() { - return invokers; - } - - NameSpaceInfo nsInfo; - std::string name; - std::string sessionId; - std::map<std::string, IOProcessor> ioProcs; - std::map<std::string, Invoker> invokers; - Arabica::DOM::Document<std::string> document; - scxml_ctx* ctx; - DataModel datamodel; - - std::map<const scxml_elem_foreach*, scxml_foreach_info*> foreachInfo; - std::deque<Event*> iq; - std::deque<Event*> eq; - - DelayedEventQueue delayQueue; - std::map<std::string, SendRequest*> sendIds; - - tthread::condition_variable monitor; - tthread::mutex mutex; + NameSpaceInfo getNameSpaceInfo() const { + return nsInfo; + } + const std::string& getName() { + return name; + } + const std::string& getSessionId() { + return sessionId; + } + const std::map<std::string, IOProcessor>& getIOProcessors() { + return ioProcs; + } + bool isInState(const std::string& stateId) { + for (int i = 0 ; i < SCXML_NUMBER_STATES; i++) { + if (scxml_states[i].name != NULL && IS_SET(i, ctx->config) && stateId == scxml_states[i].name) + return true; + } + return false; + } + Arabica::DOM::Document<std::string> getDocument() const { + return document; + } + const std::map<std::string, Invoker>& getInvokers() { + return invokers; + } + + NameSpaceInfo nsInfo; + std::string name; + std::string sessionId; + std::map<std::string, IOProcessor> ioProcs; + std::map<std::string, Invoker> invokers; + Arabica::DOM::Document<std::string> document; + scxml_ctx* ctx; + DataModel datamodel; + + std::map<const scxml_elem_foreach*, scxml_foreach_info*> foreachInfo; + std::deque<Event*> iq; + std::deque<Event*> eq; + + DelayedEventQueue delayQueue; + std::map<std::string, SendRequest*> sendIds; + + tthread::condition_variable monitor; + tthread::mutex mutex; }; int matches(const char* desc, const char* event) { - const char* dPtr = desc; - const char* ePtr = event; - while(*dPtr != 0) { - - if (*dPtr == '*' && *ePtr != 0) // something following - return true; - - // descriptor differs from event name - if (*dPtr != *ePtr) { - // move to next descriptor - while(*dPtr != ' ' && *dPtr != 0) { - dPtr++; - } - if (*dPtr == 0) - return false; - dPtr++; - ePtr = event; - } else { - // move both pointers one character - dPtr++; - ePtr++; - - } - - // descriptor is done, return match - if (((*dPtr == 0 || *dPtr == ' ') && (*ePtr == 0 || *ePtr == ' ')) || // exact match, end of string - (*dPtr == ' ' && *ePtr == '.') || (*dPtr == 0 && *ePtr == '.')) // prefix match - return true; - } - return false; + const char* dPtr = desc; + const char* ePtr = event; + while(*dPtr != 0) { + + if (*dPtr == '*' && *ePtr != 0) // something following + return true; + + // descriptor differs from event name + if (*dPtr != *ePtr) { + // move to next descriptor + while(*dPtr != ' ' && *dPtr != 0) { + dPtr++; + } + if (*dPtr == 0) + return false; + dPtr++; + ePtr = event; + } else { + // move both pointers one character + dPtr++; + ePtr++; + + } + + // descriptor is done, return match + if (((*dPtr == 0 || *dPtr == ' ') && (*ePtr == 0 || *ePtr == ' ')) || // exact match, end of string + (*dPtr == ' ' && *ePtr == '.') || (*dPtr == 0 && *ePtr == '.')) // prefix match + return true; + } + return false; } int exec_content_raise(const scxml_ctx* ctx, const char* event) { - Event* e = new Event(); - e->name = strdup(event); - - if (boost::starts_with(e->name, "error.")) { - e->eventType = Event::PLATFORM; - } else { - e->eventType = Event::INTERNAL; - } - + Event* e = new Event(); + e->name = strdup(event); + + if (boost::starts_with(e->name, "error.")) { + e->eventType = Event::PLATFORM; + } else { + e->eventType = Event::INTERNAL; + } + #ifdef SCXML_VERBOSE - printf("Raising Internal Event: %s\n", e->name.c_str()); + printf("Raising Internal Event: %s\n", e->name.c_str()); #endif - USER_DATA(ctx)->iq.push_back(e); - return SCXML_ERR_OK; + USER_DATA(ctx)->iq.push_back(e); + return SCXML_ERR_OK; } int is_true(const scxml_ctx* ctx, const char* expr) { - try { - return USER_DATA(ctx)->datamodel.evalAsBool(expr); - } catch (Event e) { - exec_content_raise(ctx, e.name.c_str()); - } - return false; + try { + return USER_DATA(ctx)->datamodel.evalAsBool(expr); + } catch (Event e) { + exec_content_raise(ctx, e.name.c_str()); + } + return false; } int is_enabled(const scxml_ctx* ctx, const scxml_transition* t, const void* e) { - Event* event = (Event*)e; - if (event == NULL) { - if (t->event == NULL) { - // spontaneous transition, null event - if (t->condition != NULL) - return is_true(ctx, t->condition); - return true; - } else { - // spontaneous transition, but real event - return false; - } - } - - // real transition, real event - if (matches(t->event, event->name.c_str())) { - if (t->condition != NULL) - return is_true(ctx, t->condition); - return true; - } - return false; + Event* event = (Event*)e; + if (event == NULL) { + if (t->event == NULL) { + // spontaneous transition, null event + if (t->condition != NULL) + return is_true(ctx, t->condition); + return true; + } else { + // spontaneous transition, but real event + return false; + } + } + + // real transition, real event + if (matches(t->event, event->name.c_str())) { + if (t->condition != NULL) + return is_true(ctx, t->condition); + return true; + } + return false; } int raise_done_event(const scxml_ctx* ctx, const scxml_state* state, const scxml_elem_donedata* donedata) { - Event* e = new Event(); - e->name = std::string("done.state.") + state->name; - - if (donedata) { - if (donedata->content != NULL) { - e->data = Data(donedata->content, Data::VERBATIM); - } else if (donedata->contentexpr != NULL) { - try { - e->data = USER_DATA(ctx)->datamodel.getStringAsData(donedata->contentexpr); - } catch (Event e) { - exec_content_raise(ctx, e.name.c_str()); - } - } else { - try { - const scxml_elem_param* param = donedata->params; - while (param && ELEM_PARAM_IS_SET(param)) { - Data paramValue; - if (param->expr != NULL) { - paramValue = USER_DATA(ctx)->datamodel.getStringAsData(param->expr); - } else if(param->location) { - paramValue = USER_DATA(ctx)->datamodel.getStringAsData(param->location); - } - e->params.insert(std::make_pair(param->name, paramValue)); - param++; - } - } catch (Event e) { - exec_content_raise(ctx, e.name.c_str()); - } - } - } + Event* e = new Event(); + e->name = std::string("done.state.") + state->name; + + if (donedata) { + if (donedata->content != NULL) { + e->data = Data(donedata->content, Data::VERBATIM); + } else if (donedata->contentexpr != NULL) { + try { + e->data = USER_DATA(ctx)->datamodel.getStringAsData(donedata->contentexpr); + } catch (Event e) { + exec_content_raise(ctx, e.name.c_str()); + } + } else { + try { + const scxml_elem_param* param = donedata->params; + while (param && ELEM_PARAM_IS_SET(param)) { + Data paramValue; + if (param->expr != NULL) { + paramValue = USER_DATA(ctx)->datamodel.getStringAsData(param->expr); + } else if(param->location) { + paramValue = USER_DATA(ctx)->datamodel.getStringAsData(param->location); + } + e->params.insert(std::make_pair(param->name, paramValue)); + param++; + } + } catch (Event e) { + exec_content_raise(ctx, e.name.c_str()); + } + } + } #ifdef SCXML_VERBOSE - printf("Raising Done Event: %s\n", e->name.c_str()); + printf("Raising Done Event: %s\n", e->name.c_str()); #endif - USER_DATA(ctx)->iq.push_back(e); - return SCXML_ERR_OK; + USER_DATA(ctx)->iq.push_back(e); + return SCXML_ERR_OK; } void delayedSend(void* ctx, std::string eventName) { - tthread::lock_guard<tthread::mutex> lock(USER_DATA(ctx)->mutex); + tthread::lock_guard<tthread::mutex> lock(USER_DATA(ctx)->mutex); - SendRequest* e = USER_DATA(ctx)->sendIds[eventName]; - if (e->target == "#_internal") { - e->eventType = Event::INTERNAL; + SendRequest* e = USER_DATA(ctx)->sendIds[eventName]; + if (e->target == "#_internal") { + e->eventType = Event::INTERNAL; #ifdef SCXML_VERBOSE - printf("Pushing Internal Event: %s\n", e->name.c_str()); + printf("Pushing Internal Event: %s\n", e->name.c_str()); #endif - USER_DATA(ctx)->iq.push_back(e); - } else { - e->eventType = Event::EXTERNAL; + USER_DATA(ctx)->iq.push_back(e); + } else { + e->eventType = Event::EXTERNAL; #ifdef SCXML_VERBOSE - printf("Pushing External Event: %s\n", e->name.c_str()); + printf("Pushing External Event: %s\n", e->name.c_str()); #endif - USER_DATA(ctx)->eq.push_back(e); - } - USER_DATA(ctx)->monitor.notify_all(); + USER_DATA(ctx)->eq.push_back(e); + } + USER_DATA(ctx)->monitor.notify_all(); } int exec_content_cancel(const scxml_ctx* ctx, const char* sendid, const char* sendidexpr) { - std::string eventId; - if (sendid != NULL) { - eventId = sendid; - } else if (sendidexpr != NULL) { - eventId = USER_DATA(ctx)->datamodel.evalAsString(sendidexpr); - } - - if (eventId.length() > 0) { - USER_DATA(ctx)->delayQueue.cancelEvent(eventId); - } else { - exec_content_raise(ctx, "error.execution"); - return SCXML_ERR_EXEC_CONTENT; - } - return SCXML_ERR_OK; + std::string eventId; + if (sendid != NULL) { + eventId = sendid; + } else if (sendidexpr != NULL) { + eventId = USER_DATA(ctx)->datamodel.evalAsString(sendidexpr); + } + + if (eventId.length() > 0) { + USER_DATA(ctx)->delayQueue.cancelEvent(eventId); + } else { + exec_content_raise(ctx, "error.execution"); + return SCXML_ERR_EXEC_CONTENT; + } + return SCXML_ERR_OK; } std::string spaceNormalize(const std::string& text) { - std::stringstream content; - std::string seperator; - - size_t start = 0; - for (int i = 0; i < text.size(); i++) { - if (isspace(text[i])) { - if (i > 0 && start < i) { - content << seperator << text.substr(start, i - start); - seperator = " "; - } - while(isspace(text[++i])); // skip whitespaces - start = i; - } else if (i + 1 == text.size()) { - content << seperator << text.substr(start, i + 1 - start); - } - } - return content.str(); + std::stringstream content; + std::string seperator; + + size_t start = 0; + for (int i = 0; i < text.size(); i++) { + if (isspace(text[i])) { + if (i > 0 && start < i) { + content << seperator << text.substr(start, i - start); + seperator = " "; + } + while(isspace(text[++i])); // skip whitespaces + start = i; + } else if (i + 1 == text.size()) { + content << seperator << text.substr(start, i + 1 - start); + } + } + return content.str(); } int exec_content_send(const scxml_ctx* ctx, const scxml_elem_send* send) { - SendRequest* e = new SendRequest(); - - std::string target; - if (send->target != NULL) { - e->target = send->target; - } else if (send->targetexpr != NULL) { - e->target = USER_DATA(ctx)->datamodel.evalAsString(send->targetexpr); - } else { - e->target = "#_external"; - } - - if (e->target.size() > 0 && (e->target[0] != '#' || e->target[1] != '_')) { - delete e; - exec_content_raise(ctx, "error.execution"); - return SCXML_ERR_INVALID_TARGET; - } - - e->origintype = "http://www.w3.org/TR/scxml/#SCXMLEventProcessor"; - e->origin = e->target; - - try { - if (send->type != NULL) { - e->type = send->type; - } else if (send->typeexpr != NULL) { - e->type = USER_DATA(ctx)->datamodel.evalAsString(send->typeexpr); - } else { - e->type = "http://www.w3.org/TR/scxml/#SCXMLEventProcessor"; - } - } catch (Event e) { - exec_content_raise(ctx, e.name.c_str()); - return SCXML_ERR_EXEC_CONTENT; - } - - // only one somewhat supported - if (e->type != "http://www.w3.org/TR/scxml/#SCXMLEventProcessor") { - delete e; - exec_content_raise(ctx, "error.execution"); - return SCXML_ERR_INVALID_TARGET; - } - - e->origintype = e->type; - - if (send->eventexpr != NULL) { - e->name = USER_DATA(ctx)->datamodel.evalAsString(send->eventexpr); - } else { - e->name = strdup(send->event); - } - - try { - const scxml_elem_param* param = send->params; - while (param && ELEM_PARAM_IS_SET(param)) { - Data paramValue; - if (param->expr != NULL) { - paramValue = USER_DATA(ctx)->datamodel.getStringAsData(param->expr); - } else if(param->location) { - paramValue = USER_DATA(ctx)->datamodel.getStringAsData(param->location); - } - e->params.insert(std::make_pair(param->name, paramValue)); - param++; - } - } catch (Event e) { - exec_content_raise(ctx, e.name.c_str()); - return SCXML_ERR_EXEC_CONTENT; - } - - try { - if (send->namelist != NULL) { - const char* bPtr = &send->namelist[0]; - const char* ePtr = bPtr; - while(*ePtr != '\0') { - ePtr++; - if (*ePtr == ' ' || *ePtr == '\0') { - std::string key(bPtr, ePtr - bPtr); - e->params.insert(std::make_pair(key, USER_DATA(ctx)->datamodel.getStringAsData(key))); - if (*ePtr == '\0') - break; - bPtr = ++ePtr; - } - } - } - } catch (Event e) { - exec_content_raise(ctx, e.name.c_str()); - return SCXML_ERR_EXEC_CONTENT; - } - - if (send->content != NULL) { - // will it parse as json? - Data d = Data::fromJSON(send->content); - if (!d.empty()) { - e->data = d; - } else { - e->data = Data(spaceNormalize(send->content), Data::VERBATIM); - } - } - - const char* sendid = NULL; - if (send->id != NULL) { - sendid = send->id; - e->sendid = sendid; - } else { - sendid = strdup(UUID::getUUID().c_str()); - if (send->idlocation != NULL) { - USER_DATA(ctx)->datamodel.assign(send->idlocation, Data(sendid, Data::VERBATIM)); - } else { - e->hideSendId = true; - } - } - - - size_t delayMs = 0; - std::string delay; - if (send->delayexpr != NULL) { - delay = USER_DATA(ctx)->datamodel.evalAsString(send->delayexpr); - } else if (send->delay != NULL) { - delay = send->delay; - } - if (delay.size() > 0) { - boost::trim(delay); - - NumAttr delayAttr(delay); - if (iequals(delayAttr.unit, "ms")) { - delayMs = strTo<uint32_t>(delayAttr.value); - } else if (iequals(delayAttr.unit, "s")) { - delayMs = strTo<double>(delayAttr.value) * 1000; - } else if (delayAttr.unit.length() == 0) { // unit less delay is interpreted as milliseconds - delayMs = strTo<uint32_t>(delayAttr.value); - } else { - std::cerr << "Cannot make sense of delay value " << delay << ": does not end in 's' or 'ms'"; - } - } - - USER_DATA(ctx)->sendIds[sendid] = e; - if (delayMs > 0) { - USER_DATA(ctx)->delayQueue.addEvent(sendid, delayedSend, delayMs, (void*)ctx); - } else { - delayedSend((void*)ctx, sendid); - } - - return SCXML_ERR_OK; + SendRequest* e = new SendRequest(); + + std::string target; + if (send->target != NULL) { + e->target = send->target; + } else if (send->targetexpr != NULL) { + e->target = USER_DATA(ctx)->datamodel.evalAsString(send->targetexpr); + } else { + e->target = "#_external"; + } + + if (e->target.size() > 0 && (e->target[0] != '#' || e->target[1] != '_')) { + delete e; + exec_content_raise(ctx, "error.execution"); + return SCXML_ERR_INVALID_TARGET; + } + + e->origintype = "http://www.w3.org/TR/scxml/#SCXMLEventProcessor"; + e->origin = e->target; + + try { + if (send->type != NULL) { + e->type = send->type; + } else if (send->typeexpr != NULL) { + e->type = USER_DATA(ctx)->datamodel.evalAsString(send->typeexpr); + } else { + e->type = "http://www.w3.org/TR/scxml/#SCXMLEventProcessor"; + } + } catch (Event e) { + exec_content_raise(ctx, e.name.c_str()); + return SCXML_ERR_EXEC_CONTENT; + } + + // only one somewhat supported + if (e->type != "http://www.w3.org/TR/scxml/#SCXMLEventProcessor") { + delete e; + exec_content_raise(ctx, "error.execution"); + return SCXML_ERR_INVALID_TARGET; + } + + e->origintype = e->type; + + if (send->eventexpr != NULL) { + e->name = USER_DATA(ctx)->datamodel.evalAsString(send->eventexpr); + } else { + e->name = strdup(send->event); + } + + try { + const scxml_elem_param* param = send->params; + while (param && ELEM_PARAM_IS_SET(param)) { + Data paramValue; + if (param->expr != NULL) { + paramValue = USER_DATA(ctx)->datamodel.getStringAsData(param->expr); + } else if(param->location) { + paramValue = USER_DATA(ctx)->datamodel.getStringAsData(param->location); + } + e->params.insert(std::make_pair(param->name, paramValue)); + param++; + } + } catch (Event e) { + exec_content_raise(ctx, e.name.c_str()); + return SCXML_ERR_EXEC_CONTENT; + } + + try { + if (send->namelist != NULL) { + const char* bPtr = &send->namelist[0]; + const char* ePtr = bPtr; + while(*ePtr != '\0') { + ePtr++; + if (*ePtr == ' ' || *ePtr == '\0') { + std::string key(bPtr, ePtr - bPtr); + e->params.insert(std::make_pair(key, USER_DATA(ctx)->datamodel.getStringAsData(key))); + if (*ePtr == '\0') + break; + bPtr = ++ePtr; + } + } + } + } catch (Event e) { + exec_content_raise(ctx, e.name.c_str()); + return SCXML_ERR_EXEC_CONTENT; + } + + if (send->content != NULL) { + // will it parse as json? + Data d = Data::fromJSON(send->content); + if (!d.empty()) { + e->data = d; + } else { + e->data = Data(spaceNormalize(send->content), Data::VERBATIM); + } + } + + const char* sendid = NULL; + if (send->id != NULL) { + sendid = send->id; + e->sendid = sendid; + } else { + sendid = strdup(UUID::getUUID().c_str()); + if (send->idlocation != NULL) { + USER_DATA(ctx)->datamodel.assign(send->idlocation, Data(sendid, Data::VERBATIM)); + } else { + e->hideSendId = true; + } + } + + + size_t delayMs = 0; + std::string delay; + if (send->delayexpr != NULL) { + delay = USER_DATA(ctx)->datamodel.evalAsString(send->delayexpr); + } else if (send->delay != NULL) { + delay = send->delay; + } + if (delay.size() > 0) { + boost::trim(delay); + + NumAttr delayAttr(delay); + if (iequals(delayAttr.unit, "ms")) { + delayMs = strTo<uint32_t>(delayAttr.value); + } else if (iequals(delayAttr.unit, "s")) { + delayMs = strTo<double>(delayAttr.value) * 1000; + } else if (delayAttr.unit.length() == 0) { // unit less delay is interpreted as milliseconds + delayMs = strTo<uint32_t>(delayAttr.value); + } else { + std::cerr << "Cannot make sense of delay value " << delay << ": does not end in 's' or 'ms'"; + } + } + + USER_DATA(ctx)->sendIds[sendid] = e; + if (delayMs > 0) { + USER_DATA(ctx)->delayQueue.addEvent(sendid, delayedSend, delayMs, (void*)ctx); + } else { + delayedSend((void*)ctx, sendid); + } + + return SCXML_ERR_OK; } int exec_content_init(const scxml_ctx* ctx, const scxml_elem_data* data) { - while(ELEM_DATA_IS_SET(data)) { - Data d; - if (data->expr != NULL) { - d = Data(data->expr, Data::INTERPRETED); - } else if (data->content != NULL) { - d = Data(data->content, Data::INTERPRETED); - } else { - d = Data("undefined", Data::INTERPRETED); - } - try { - USER_DATA(ctx)->datamodel.init(data->id, d); - } catch (Event e) { - exec_content_raise(ctx, e.name.c_str()); - } - data++; - } - return SCXML_ERR_OK; + while(ELEM_DATA_IS_SET(data)) { + Data d; + if (data->expr != NULL) { + d = Data(data->expr, Data::INTERPRETED); + } else if (data->content != NULL) { + d = Data(data->content, Data::INTERPRETED); + } else { + d = Data("undefined", Data::INTERPRETED); + } + try { + USER_DATA(ctx)->datamodel.init(data->id, d); + } catch (Event e) { + exec_content_raise(ctx, e.name.c_str()); + } + data++; + } + return SCXML_ERR_OK; } int exec_content_assign(const scxml_ctx* ctx, const char* location, const char* expr) { - std::string key = location; - if (key == "_sessionid" || key == "_name" || key == "_ioprocessors" || key == "_invokers" || key == "_event") { - exec_content_raise(ctx, "error.execution"); - return SCXML_ERR_EXEC_CONTENT; - } - - try { - Data d(expr, Data::INTERPRETED); - USER_DATA(ctx)->datamodel.assign(key, d); - } catch (Event e) { - exec_content_raise(ctx, e.name.c_str()); - return SCXML_ERR_EXEC_CONTENT; - } - return SCXML_ERR_OK; + std::string key = location; + if (key == "_sessionid" || key == "_name" || key == "_ioprocessors" || key == "_invokers" || key == "_event") { + exec_content_raise(ctx, "error.execution"); + return SCXML_ERR_EXEC_CONTENT; + } + + try { + Data d(expr, Data::INTERPRETED); + USER_DATA(ctx)->datamodel.assign(key, d); + } catch (Event e) { + exec_content_raise(ctx, e.name.c_str()); + return SCXML_ERR_EXEC_CONTENT; + } + return SCXML_ERR_OK; } int exec_content_foreach_init(const scxml_ctx* ctx, const scxml_elem_foreach* foreach) { - try { - scxml_foreach_info* feInfo = (scxml_foreach_info*)malloc(sizeof(scxml_foreach_info)); - USER_DATA(ctx)->foreachInfo[foreach] = feInfo; - - feInfo->iterations = USER_DATA(ctx)->datamodel.getLength(foreach->array); - feInfo->currIteration = 0; - } catch (Event e) { - exec_content_raise(ctx, e.name.c_str()); - return SCXML_ERR_EXEC_CONTENT; - } - return SCXML_ERR_OK; + try { + scxml_foreach_info* feInfo = (scxml_foreach_info*)malloc(sizeof(scxml_foreach_info)); + USER_DATA(ctx)->foreachInfo[foreach] = feInfo; + + feInfo->iterations = USER_DATA(ctx)->datamodel.getLength(foreach->array); + feInfo->currIteration = 0; + } catch (Event e) { + exec_content_raise(ctx, e.name.c_str()); + return SCXML_ERR_EXEC_CONTENT; + } + return SCXML_ERR_OK; } int exec_content_foreach_next(const scxml_ctx* ctx, const scxml_elem_foreach* foreach) { - try { - scxml_foreach_info* feInfo = USER_DATA(ctx)->foreachInfo[foreach]; - if (feInfo->currIteration < feInfo->iterations) { - USER_DATA(ctx)->datamodel.setForeach((foreach->item != NULL ? foreach->item : ""), - (foreach->array != NULL ? foreach->array : ""), - (foreach->index != NULL ? foreach->index : ""), - feInfo->currIteration); - feInfo->currIteration++; - return SCXML_ERR_OK; - } - } catch (Event e) { - exec_content_raise(ctx, e.name.c_str()); - free(USER_DATA(ctx)->foreachInfo[foreach]); - USER_DATA(ctx)->foreachInfo.erase(foreach); - return SCXML_ERR_EXEC_CONTENT; - } - return SCXML_ERR_FOREACH_DONE; + try { + scxml_foreach_info* feInfo = USER_DATA(ctx)->foreachInfo[foreach]; + if (feInfo->currIteration < feInfo->iterations) { + USER_DATA(ctx)->datamodel.setForeach((foreach->item != NULL ? foreach->item : ""), + (foreach->array != NULL ? foreach->array : ""), + (foreach->index != NULL ? foreach->index : ""), + feInfo->currIteration); + feInfo->currIteration++; + return SCXML_ERR_OK; + } + } catch (Event e) { + exec_content_raise(ctx, e.name.c_str()); + free(USER_DATA(ctx)->foreachInfo[foreach]); + USER_DATA(ctx)->foreachInfo.erase(foreach); + return SCXML_ERR_EXEC_CONTENT; + } + return SCXML_ERR_FOREACH_DONE; } int exec_content_foreach_done(const scxml_ctx* ctx, const scxml_elem_foreach* foreach) { - free(USER_DATA(ctx)->foreachInfo[foreach]); - USER_DATA(ctx)->foreachInfo.erase(foreach); - return SCXML_ERR_OK; + free(USER_DATA(ctx)->foreachInfo[foreach]); + USER_DATA(ctx)->foreachInfo.erase(foreach); + return SCXML_ERR_OK; } int exec_content_log(const scxml_ctx* ctx, const char* label, const char* expr) { - try { - if (label != 0) { + try { + if (label != 0) { // printf("%s: %s\n", label, USER_DATA(ctx)->datamodel.evalAsString(expr).c_str()); - } else { + } else { // printf("%s\n", USER_DATA(ctx)->datamodel.evalAsString(expr).c_str()); - } - } catch (Event e) { - exec_content_raise(ctx, e.name.c_str()); - return SCXML_ERR_EXEC_CONTENT; - } - - return SCXML_ERR_OK; + } + } catch (Event e) { + exec_content_raise(ctx, e.name.c_str()); + return SCXML_ERR_EXEC_CONTENT; + } + + return SCXML_ERR_OK; } int exec_content_script(const scxml_ctx* ctx, const char* src, const char* content) { - if (content != NULL) { - USER_DATA(ctx)->datamodel.eval(Arabica::DOM::Element<std::string>(), content); - } else if (src != NULL) { - return SCXML_ERR_UNSUPPORTED; - } - return SCXML_ERR_OK; + if (content != NULL) { + USER_DATA(ctx)->datamodel.eval(Arabica::DOM::Element<std::string>(), content); + } else if (src != NULL) { + return SCXML_ERR_UNSUPPORTED; + } + return SCXML_ERR_OK; } void* dequeue_external(const scxml_ctx* ctx) { - tthread::lock_guard<tthread::mutex> lock(USER_DATA(ctx)->mutex); - while (USER_DATA(ctx)->eq.size() == 0) { - USER_DATA(ctx)->monitor.wait(USER_DATA(ctx)->mutex); - } - Event* e = USER_DATA(ctx)->eq.front(); - USER_DATA(ctx)->eq.pop_front(); - USER_DATA(ctx)->datamodel.setEvent(*e); + tthread::lock_guard<tthread::mutex> lock(USER_DATA(ctx)->mutex); + while (USER_DATA(ctx)->eq.size() == 0) { + USER_DATA(ctx)->monitor.wait(USER_DATA(ctx)->mutex); + } + Event* e = USER_DATA(ctx)->eq.front(); + USER_DATA(ctx)->eq.pop_front(); + USER_DATA(ctx)->datamodel.setEvent(*e); #ifdef SCXML_VERBOSE - printf("Popping External Event: %s\n", e->name.c_str()); + printf("Popping External Event: %s\n", e->name.c_str()); #endif - return e; + return e; } void* dequeue_internal(const scxml_ctx* ctx) { - if (USER_DATA(ctx)->iq.size() == 0) - return NULL; - Event* e = USER_DATA(ctx)->iq.front(); - USER_DATA(ctx)->iq.pop_front(); - USER_DATA(ctx)->datamodel.setEvent(*e); + if (USER_DATA(ctx)->iq.size() == 0) + return NULL; + Event* e = USER_DATA(ctx)->iq.front(); + USER_DATA(ctx)->iq.pop_front(); + USER_DATA(ctx)->datamodel.setEvent(*e); #ifdef SCXML_VERBOSE - printf("Popping Internal Event: %s\n", e->name.c_str()); + printf("Popping Internal Event: %s\n", e->name.c_str()); #endif - return e; + return e; } int main(int argc, char** argv) { - + #ifdef APPLE - mach_timebase_info_data_t timebase_info; - mach_timebase_info(&timebase_info); - - const uint64_t NANOS_PER_MSEC = 1000000ULL; - double clock2abs = ((double)timebase_info.denom / (double)timebase_info.numer) * NANOS_PER_MSEC; - - thread_time_constraint_policy_data_t policy; - policy.period = 0; - policy.computation = (uint32_t)(5 * clock2abs); // 5 ms of work - policy.constraint = (uint32_t)(10 * clock2abs); - policy.preemptible = FALSE; - - int kr = thread_policy_set(pthread_mach_thread_np(pthread_self()), - THREAD_TIME_CONSTRAINT_POLICY, - (thread_policy_t)&policy, - THREAD_TIME_CONSTRAINT_POLICY_COUNT); - if (kr != KERN_SUCCESS) { - mach_error("thread_policy_set:", kr); - exit(1); - } + mach_timebase_info_data_t timebase_info; + mach_timebase_info(&timebase_info); + + const uint64_t NANOS_PER_MSEC = 1000000ULL; + double clock2abs = ((double)timebase_info.denom / (double)timebase_info.numer) * NANOS_PER_MSEC; + + thread_time_constraint_policy_data_t policy; + policy.period = 0; + policy.computation = (uint32_t)(5 * clock2abs); // 5 ms of work + policy.constraint = (uint32_t)(10 * clock2abs); + policy.preemptible = FALSE; + + int kr = thread_policy_set(pthread_mach_thread_np(pthread_self()), + THREAD_TIME_CONSTRAINT_POLICY, + (thread_policy_t)&policy, + THREAD_TIME_CONSTRAINT_POLICY_COUNT); + if (kr != KERN_SUCCESS) { + mach_error("thread_policy_set:", kr); + exit(1); + } #endif - - int err; - size_t benchmarkRuns = 1; - const char* envBenchmarkRuns = getenv("USCXML_BENCHMARK_ITERATIONS"); - if (envBenchmarkRuns != NULL) { - benchmarkRuns = strTo<size_t>(envBenchmarkRuns); - } - - - size_t remainingRuns = benchmarkRuns; - - // setup info object required for datamodel - GenCInterpreterInfo interpreterInfo; - interpreterInfo.name = SCXML_MACHINE_NAME; - interpreterInfo.sessionId = "rfwef"; - interpreterInfo.delayQueue.start(); - - scxml_ctx ctx; - interpreterInfo.ctx = &ctx; - - double avg = 0; - size_t microSteps = 0; + + int err; + size_t benchmarkRuns = 1; + const char* envBenchmarkRuns = getenv("USCXML_BENCHMARK_ITERATIONS"); + if (envBenchmarkRuns != NULL) { + benchmarkRuns = strTo<size_t>(envBenchmarkRuns); + } + + + size_t remainingRuns = benchmarkRuns; + + // setup info object required for datamodel + GenCInterpreterInfo interpreterInfo; + interpreterInfo.name = SCXML_MACHINE_NAME; + interpreterInfo.sessionId = "rfwef"; + interpreterInfo.delayQueue.start(); + + scxml_ctx ctx; + interpreterInfo.ctx = &ctx; + + double avg = 0; + size_t microSteps = 0; #ifdef BUILD_PROFILING - double avgDm = 0; + double avgDm = 0; #endif - while(remainingRuns-- > 0) { - memset(&ctx, 0, sizeof(scxml_ctx)); - - // fresh dm (expensive :( ) - interpreterInfo.datamodel = Factory::getInstance()->createDataModel("ecmascript", &interpreterInfo); - - // set info object as user data - ctx.user_data = (void*)&interpreterInfo; - - // register callbacks with scxml context - ctx.is_enabled = &is_enabled; - ctx.is_true = &is_true; - ctx.raise_done_event = &raise_done_event; - - ctx.exec_content_send = &exec_content_send; - ctx.exec_content_raise = &exec_content_raise; - ctx.exec_content_cancel = &exec_content_cancel; - ctx.exec_content_log = &exec_content_log; - ctx.exec_content_assign = &exec_content_assign; - ctx.exec_content_foreach_init = &exec_content_foreach_init; - ctx.exec_content_foreach_next = &exec_content_foreach_next; - ctx.exec_content_foreach_done = &exec_content_foreach_done; - ctx.dequeue_external = &dequeue_external; - ctx.dequeue_internal = &dequeue_internal; - ctx.exec_content_init = &exec_content_init; - ctx.exec_content_script = &exec_content_script; - - Timer t; - t.start(); - - microSteps = 0; - while((err = scxml_step(&ctx)) == SCXML_ERR_OK) { microSteps++; } - assert(ctx.flags & SCXML_CTX_TOP_LEVEL_FINAL); - - t.stop(); - avg += t.elapsed; + while(remainingRuns-- > 0) { + memset(&ctx, 0, sizeof(scxml_ctx)); + + // fresh dm (expensive :( ) + interpreterInfo.datamodel = Factory::getInstance()->createDataModel("ecmascript", &interpreterInfo); + + // set info object as user data + ctx.user_data = (void*)&interpreterInfo; + + // register callbacks with scxml context + ctx.is_enabled = &is_enabled; + ctx.is_true = &is_true; + ctx.raise_done_event = &raise_done_event; + + ctx.exec_content_send = &exec_content_send; + ctx.exec_content_raise = &exec_content_raise; + ctx.exec_content_cancel = &exec_content_cancel; + ctx.exec_content_log = &exec_content_log; + ctx.exec_content_assign = &exec_content_assign; + ctx.exec_content_foreach_init = &exec_content_foreach_init; + ctx.exec_content_foreach_next = &exec_content_foreach_next; + ctx.exec_content_foreach_done = &exec_content_foreach_done; + ctx.dequeue_external = &dequeue_external; + ctx.dequeue_internal = &dequeue_internal; + ctx.exec_content_init = &exec_content_init; + ctx.exec_content_script = &exec_content_script; + + Timer t; + t.start(); + + microSteps = 0; + while((err = scxml_step(&ctx)) == SCXML_ERR_OK) { + microSteps++; + } + assert(ctx.flags & SCXML_CTX_TOP_LEVEL_FINAL); + + t.stop(); + avg += t.elapsed; #ifdef BUILD_PROFILING - avgDm += interpreterInfo.datamodel.timer.elapsed; - interpreterInfo.datamodel.timer.elapsed = 0; + avgDm += interpreterInfo.datamodel.timer.elapsed; + interpreterInfo.datamodel.timer.elapsed = 0; #endif - size_t passIdx = 0; - for (int i = 0; i < SCXML_NUMBER_STATES; i++) { - if (scxml_states[i].name && strcmp(scxml_states[i].name, "pass") == 0) { - passIdx = i; - break; - } - } - - assert(IS_SET(passIdx, ctx.config)); - interpreterInfo.delayQueue.cancelAllEvents(); - interpreterInfo.eq.clear(); - interpreterInfo.iq.clear(); - } - - // 14.25311111 us per microstep - // 1.923466667 us - std::cout << (avg * 1000.0) / (double)benchmarkRuns << " ms on average" << std::endl; - std::cout << microSteps << " microsteps per iteration (" << (avg * 1000.0) / ((double)benchmarkRuns * (double)microSteps) << " ms per microstep)" << std::endl; + size_t passIdx = 0; + for (int i = 0; i < SCXML_NUMBER_STATES; i++) { + if (scxml_states[i].name && strcmp(scxml_states[i].name, "pass") == 0) { + passIdx = i; + break; + } + } + + assert(IS_SET(passIdx, ctx.config)); + interpreterInfo.delayQueue.cancelAllEvents(); + interpreterInfo.eq.clear(); + interpreterInfo.iq.clear(); + } + + // 14.25311111 us per microstep + // 1.923466667 us + std::cout << (avg * 1000.0) / (double)benchmarkRuns << " ms on average" << std::endl; + std::cout << microSteps << " microsteps per iteration (" << (avg * 1000.0) / ((double)benchmarkRuns * (double)microSteps) << " ms per microstep)" << std::endl; #ifdef BUILD_PROFILING - std::cout << (avgDm * 1000.0) / (double)benchmarkRuns << " ms in datamodel" << std::endl; - std::cout << ((avg - avgDm) * 1000.0) / ((double)benchmarkRuns * (double)microSteps) << " ms per microstep \\wo datamodel" << std::endl; + std::cout << (avgDm * 1000.0) / (double)benchmarkRuns << " ms in datamodel" << std::endl; + std::cout << ((avg - avgDm) * 1000.0) / ((double)benchmarkRuns * (double)microSteps) << " ms per microstep \\wo datamodel" << std::endl; #endif - interpreterInfo.delayQueue.stop(); - tthread::this_thread::sleep_for(tthread::chrono::milliseconds(100)); - return EXIT_SUCCESS; + interpreterInfo.delayQueue.stop(); + tthread::this_thread::sleep_for(tthread::chrono::milliseconds(100)); + return EXIT_SUCCESS; }
\ No newline at end of file diff --git a/test/src/test-datamodel.cpp b/test/src/test-datamodel.cpp index 4b93b4d..12f74e6 100644 --- a/test/src/test-datamodel.cpp +++ b/test/src/test-datamodel.cpp @@ -16,15 +16,15 @@ using namespace boost; class TestDataModelExtension : public DataModelExtension { public: TestDataModelExtension() {} - + std::string provides() { return "_x.platform.pool"; } - + Data getValueOf(const std::string& member) { return Data(true); } - + void setValueOf(const std::string& member, const Data& data) { std::cout << "Setting " << member << " to " << std::endl << Data::toJSON(data); } @@ -497,20 +497,20 @@ int main(int argc, char** argv) { std::cout << content << std::endl; assert(boost::equals(content, "There are 12 monkeys! Really 12 monkeys!")); } - + { std::string xml = - "<scxml datamodel=\"ecmascript\">" - " <script src=\"http://uscxml.tk.informatik.tu-darmstadt.de/scripts/dump.js\" />" - " <state id=\"s1\">" - " <onentry>" - " <script>_x.platform.pool('memeber.second', { foo: 12, bar: 34})</script>" - " <log label=\"ext\" expr=\"dump(_x.platform.pool('member.first'))\" />" - " </onentry>" - " <transition target=\"done\" />" - " </state>" - " <final id=\"done\" />" - "</scxml>"; + "<scxml datamodel=\"ecmascript\">" + " <script src=\"http://uscxml.tk.informatik.tu-darmstadt.de/scripts/dump.js\" />" + " <state id=\"s1\">" + " <onentry>" + " <script>_x.platform.pool('memeber.second', { foo: 12, bar: 34})</script>" + " <log label=\"ext\" expr=\"dump(_x.platform.pool('member.first'))\" />" + " </onentry>" + " <transition target=\"done\" />" + " </state>" + " <final id=\"done\" />" + "</scxml>"; TestDataModelExtension ext; Interpreter interpreter = Interpreter::fromXML(xml, ""); @@ -522,6 +522,6 @@ int main(int argc, char** argv) { state = interpreter.step(); } while (state != USCXML_FINISHED && state!= USCXML_DESTROYED); - + } }
\ No newline at end of file diff --git a/test/src/test-doneevent.cpp b/test/src/test-doneevent.cpp index d49f8e2..0330512 100644 --- a/test/src/test-doneevent.cpp +++ b/test/src/test-doneevent.cpp @@ -4,60 +4,63 @@ using namespace uscxml; // -- Issue 56 on github int main(int argc, char** argv) { - std::deque<std::string> messageQueue; - messageQueue.push_back("a"); - messageQueue.push_back("b"); - messageQueue.push_back("c"); - messageQueue.push_back("d"); - - const char* scxmlContent = - "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" - "<scxml xmlns=\"http://www.w3.org/2005/07/scxml\" version=\"1.0\" initial=\"initial_state\">" - " <state id=\"initial_state\">" - " <transition event=\"a\" target=\"parallel_state\"/>" - " </state>" - " <parallel id=\"parallel_state\">" - " <transition event=\"done.state.parallel_state\" target=\"join_state\"/>" - " <state id=\"p1out\" initial=\"p1\">" - " <state id=\"p1\">" - " <transition event=\"b\" target=\"p11\"/>" - " </state>" - " <final id=\"p11\"/>" - " </state>" - " <state id=\"p2out\" initial=\"p2\">" - " <state id=\"p2\">" - " <transition event=\"c\" target=\"p21\"/>" - " </state>" - " <final id=\"p21\"/>" - " </state>" - " </parallel>" - " <state id=\"join_state\">" - " <transition event=\"d\" target=\"final_state\"/>" - " </state>" - " <final id=\"final_state\"/>" - "</scxml>"; - - std::string msg; - - uscxml::Interpreter scxml = uscxml::Interpreter::fromXML(scxmlContent, ""); - scxml.addMonitor(new StateTransitionMonitor()); - - uscxml::InterpreterState state; - // assume initial stable configuration - do { state = scxml.step(); } while(state > 0); - - while(state != uscxml::USCXML_FINISHED && !messageQueue.empty()) - { - msg = messageQueue.front(); - messageQueue.pop_front(); - - scxml.receive(uscxml::Event(msg, uscxml::Event::EXTERNAL)); - - // step to next stable configuration - do { state = scxml.step(); } while(state > 0); - - } - - return EXIT_SUCCESS; + std::deque<std::string> messageQueue; + messageQueue.push_back("a"); + messageQueue.push_back("b"); + messageQueue.push_back("c"); + messageQueue.push_back("d"); + + const char* scxmlContent = + "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" + "<scxml xmlns=\"http://www.w3.org/2005/07/scxml\" version=\"1.0\" initial=\"initial_state\">" + " <state id=\"initial_state\">" + " <transition event=\"a\" target=\"parallel_state\"/>" + " </state>" + " <parallel id=\"parallel_state\">" + " <transition event=\"done.state.parallel_state\" target=\"join_state\"/>" + " <state id=\"p1out\" initial=\"p1\">" + " <state id=\"p1\">" + " <transition event=\"b\" target=\"p11\"/>" + " </state>" + " <final id=\"p11\"/>" + " </state>" + " <state id=\"p2out\" initial=\"p2\">" + " <state id=\"p2\">" + " <transition event=\"c\" target=\"p21\"/>" + " </state>" + " <final id=\"p21\"/>" + " </state>" + " </parallel>" + " <state id=\"join_state\">" + " <transition event=\"d\" target=\"final_state\"/>" + " </state>" + " <final id=\"final_state\"/>" + "</scxml>"; + + std::string msg; + + uscxml::Interpreter scxml = uscxml::Interpreter::fromXML(scxmlContent, ""); + scxml.addMonitor(new StateTransitionMonitor()); + + uscxml::InterpreterState state; + // assume initial stable configuration + do { + state = scxml.step(); + } while(state > 0); + + while(state != uscxml::USCXML_FINISHED && !messageQueue.empty()) { + msg = messageQueue.front(); + messageQueue.pop_front(); + + scxml.receive(uscxml::Event(msg, uscxml::Event::EXTERNAL)); + + // step to next stable configuration + do { + state = scxml.step(); + } while(state > 0); + + } + + return EXIT_SUCCESS; }
\ No newline at end of file diff --git a/test/src/test-flat-stateid.cpp b/test/src/test-flat-stateid.cpp index fcf50b7..10d83eb 100644 --- a/test/src/test-flat-stateid.cpp +++ b/test/src/test-flat-stateid.cpp @@ -63,11 +63,11 @@ int main(int argc, char** argv) { // these will match uscxml::HistoryTransitionClass histClass1Match1("history:{h0:{s1, s2, s3}}", "history:{h0:{s0}}"); assert(histClass1.matches(histClass1Match1)); - + histClass1.merge(histClass1Match1); assert(histClass1.toRemember.at("h0").find("s0") != histClass1.toRemember.at("h0").end()); assert(histClass1.toRemember.at("h0").size() == 1); - + assert(histClass1.toForget.at("h0").find("s1") != histClass1.toForget.at("h0").end()); assert(histClass1.toForget.at("h0").find("s2") != histClass1.toForget.at("h0").end()); assert(histClass1.toForget.at("h0").find("s3") != histClass1.toForget.at("h0").end()); diff --git a/test/src/test-issue-reporting.cpp b/test/src/test-issue-reporting.cpp index 9750c58..84cc096 100644 --- a/test/src/test-issue-reporting.cpp +++ b/test/src/test-issue-reporting.cpp @@ -7,11 +7,11 @@ using namespace uscxml; std::set<std::string> issueLocationsForXML(const std::string xml) { Interpreter interpreter = Interpreter::fromXML(xml, ""); - // common xmlns and version requirement on scxml attribute - interpreter.getDocument().getDocumentElement().setAttribute("xmlns", "http://www.w3.org/2005/07/scxml"); - interpreter.getDocument().getDocumentElement().setAttribute("version", "1.0"); + // common xmlns and version requirement on scxml attribute + interpreter.getDocument().getDocumentElement().setAttribute("xmlns", "http://www.w3.org/2005/07/scxml"); + interpreter.getDocument().getDocumentElement().setAttribute("version", "1.0"); - std::list<InterpreterIssue> issues = interpreter.validate(); + std::list<InterpreterIssue> issues = interpreter.validate(); std::set<std::string> issueLocations; @@ -101,7 +101,7 @@ int main(int argc, char** argv) { if (0) { // State has no 'id' attribute - // *** This is not actually an error! *** + // *** This is not actually an error! *** const char* xml = "<scxml datamodel=\"ecmascript\">" " <state>" @@ -142,250 +142,250 @@ int main(int argc, char** argv) { assert(issueLocations.size() == 1); } - if (1) { - // Useless history 1 - - const char* xml = - "<scxml datamodel=\"ecmascript\">" - " <state id=\"start\" initial=\"bar\">" - " <history id=\"bar\" />" - " <state id=\"baz\" />" - " <transition event=\"e.foo\" target=\"done\" />" - " <transition event=\"e.bar\" target=\"baz\" />" - " </state>" - " <final id=\"done\" />" - "</scxml>"; - - std::set<std::string> issueLocations = issueLocationsForXML(xml); - assert(issueLocations.find("//history[@id=\"bar\"]") != issueLocations.end()); - assert(issueLocations.size() == 1); - } - - if (1) { - // Useless history 2 - - const char* xml = - "<scxml datamodel=\"ecmascript\">" - " <state id=\"start\" initial=\"bar\">" - " <history id=\"bar\">" - " <transition target=\"foo\" />" - " </history>" - " <transition target=\"done\" />" - " <state id=\"foo\" />" - " </state>" - " <final id=\"done\" />" - "</scxml>"; - - std::set<std::string> issueLocations = issueLocationsForXML(xml); - assert(issueLocations.find("//history[@id=\"bar\"]") != issueLocations.end()); - assert(issueLocations.size() == 1); - } - - if (1) { - // No legal completion - - const char* xml = - "<scxml datamodel=\"ecmascript\">" - " <state id=\"start\" initial=\"foo bar\">" - " <state id=\"foo\" />" - " <state id=\"bar\" />" - " <transition target=\"foo bar\" />" - " </state>" - "</scxml>"; - - std::set<std::string> issueLocations = issueLocationsForXML(xml); - assert(issueLocations.find("//state[@id=\"start\"]") != issueLocations.end()); - assert(issueLocations.find("//state[@id=\"start\"]/transition[1]") != issueLocations.end()); - assert(issueLocations.size() == 2); - } - - if (1) { - // attribute constraints - - { - // initial attribute and <initial> child - const char* xml = - "<scxml datamodel=\"ecmascript\">" - " <state id=\"start\" initial=\"foo\">" - " <initial>" - " <transition target=\"foo\" />" - " </initial>" - " <state id=\"foo\" />" - " </state>" - "</scxml>"; - - std::set<std::string> issueLocations = issueLocationsForXML(xml); - assert(issueLocations.find("//state[@id=\"start\"]") != issueLocations.end()); - assert(issueLocations.size() == 1); - } - - { - // initial attribute with atomic state - const char* xml = - "<scxml datamodel=\"ecmascript\">" - " <state id=\"start\" initial=\"\" />" - "</scxml>"; - - std::set<std::string> issueLocations = issueLocationsForXML(xml); - assert(issueLocations.find("//state[@id=\"start\"]") != issueLocations.end()); - assert(issueLocations.size() == 1); - } - - { - // initial child with atomic state - const char* xml = - "<scxml datamodel=\"ecmascript\">" - " <state id=\"start\">" - " <initial>" - " <transition target=\"start\" />" - " </initial>" - " </state>" - "</scxml>"; - - std::set<std::string> issueLocations = issueLocationsForXML(xml); - assert(issueLocations.find("//state[@id=\"start\"]") != issueLocations.end()); - assert(issueLocations.size() == 2); // also invalid non-child target state in initial - } - - // combinations of namelist, content and param - { - // send with content and namelist, not allowed - const char* xml = - "<scxml datamodel=\"ecmascript\">" - " <state id=\"start\">" - " <onentry>" - " <send target=\"#_external\" namelist=\"var1\">" - " <content>Foo!</content>" - " </send>" - " </onentry>" - " </state>" - "</scxml>"; - - std::set<std::string> issueLocations = issueLocationsForXML(xml); - assert(issueLocations.find("//state[@id=\"start\"]/onentry[1]/send[1]") != issueLocations.end()); - assert(issueLocations.size() == 1); - } - - { - // send with content and params, not allowed - const char* xml = - "<scxml datamodel=\"ecmascript\">" - " <state id=\"start\">" - " <onentry>" - " <send target=\"#_external\">" - " <param name=\"foo\" expr=\"3\" />" - " <content>Foo!</content>" - " </send>" - " </onentry>" - " </state>" - "</scxml>"; - - std::set<std::string> issueLocations = issueLocationsForXML(xml); - assert(issueLocations.find("//state[@id=\"start\"]/onentry[1]/send[1]") != issueLocations.end()); - assert(issueLocations.size() == 1); - } - - { - // send with params and namelist, perfectly acceptable - const char* xml = - "<scxml datamodel=\"ecmascript\">" - " <state id=\"start\">" - " <onentry>" - " <send target=\"#_external\" namelist=\"foo\">" - " <param name=\"foo\" expr=\"3\" />" - " </send>" - " </onentry>" - " </state>" - "</scxml>"; - - std::set<std::string> issueLocations = issueLocationsForXML(xml); - assert(issueLocations.size() == 0); - } - - { - // invoke with content and src, not allowed - const char* xml = - "<scxml datamodel=\"ecmascript\">" - " <state id=\"start\">" - " <invoke type=\"scxml\" src=\"var1\">" - " <content>Foo!</content>" - " </invoke>" - " </state>" - "</scxml>"; - - std::set<std::string> issueLocations = issueLocationsForXML(xml); - assert(issueLocations.find("//state[@id=\"start\"]/invoke[1]") != issueLocations.end()); - assert(issueLocations.size() == 1); - } - - { - // invoke with namelist and param, not allowed - const char* xml = - "<scxml datamodel=\"ecmascript\">" - " <state id=\"start\">" - " <invoke type=\"scxml\" namelist=\"var1\">" - " <param name=\"foo\" expr=\"3\" />" - " </invoke>" - " </state>" - "</scxml>"; - - std::set<std::string> issueLocations = issueLocationsForXML(xml); - assert(issueLocations.find("//state[@id=\"start\"]/invoke[1]") != issueLocations.end()); - assert(issueLocations.size() == 1); - } - - { - // invoke with param and content, perfectly acceptable - const char* xml = - "<scxml datamodel=\"ecmascript\">" - " <state id=\"start\">" - " <invoke type=\"scxml\">" - " <param name=\"foo\" expr=\"3\" />" - " <content>Foo!</content>" - " </invoke>" - " </state>" - "</scxml>"; - - std::set<std::string> issueLocations = issueLocationsForXML(xml); - assert(issueLocations.size() == 0); - } - - { - // invoke with namelist and content, perfectly acceptable - const char* xml = - "<scxml datamodel=\"ecmascript\">" - " <state id=\"start\">" - " <invoke type=\"scxml\" namelist=\"var1\">" - " <content>Foo!</content>" - " </invoke>" - " </state>" - "</scxml>"; - - std::set<std::string> issueLocations = issueLocationsForXML(xml); - assert(issueLocations.size() == 0); - } - - { - // donedata with content and param, not allowed - const char* xml = - "<scxml datamodel=\"ecmascript\">" - " <state id=\"start\">" - " <donedata>" - " <param name=\"foo\" expr=\"3\" />" - " <content>Foo!</content>" - " </donedata>" - " </state>" - "</scxml>"; - - std::set<std::string> issueLocations = issueLocationsForXML(xml); - assert(issueLocations.find("//state[@id=\"start\"]/donedata[1]") != issueLocations.end()); - assert(issueLocations.size() == 1); - } - - - } - - + if (1) { + // Useless history 1 + + const char* xml = + "<scxml datamodel=\"ecmascript\">" + " <state id=\"start\" initial=\"bar\">" + " <history id=\"bar\" />" + " <state id=\"baz\" />" + " <transition event=\"e.foo\" target=\"done\" />" + " <transition event=\"e.bar\" target=\"baz\" />" + " </state>" + " <final id=\"done\" />" + "</scxml>"; + + std::set<std::string> issueLocations = issueLocationsForXML(xml); + assert(issueLocations.find("//history[@id=\"bar\"]") != issueLocations.end()); + assert(issueLocations.size() == 1); + } + + if (1) { + // Useless history 2 + + const char* xml = + "<scxml datamodel=\"ecmascript\">" + " <state id=\"start\" initial=\"bar\">" + " <history id=\"bar\">" + " <transition target=\"foo\" />" + " </history>" + " <transition target=\"done\" />" + " <state id=\"foo\" />" + " </state>" + " <final id=\"done\" />" + "</scxml>"; + + std::set<std::string> issueLocations = issueLocationsForXML(xml); + assert(issueLocations.find("//history[@id=\"bar\"]") != issueLocations.end()); + assert(issueLocations.size() == 1); + } + + if (1) { + // No legal completion + + const char* xml = + "<scxml datamodel=\"ecmascript\">" + " <state id=\"start\" initial=\"foo bar\">" + " <state id=\"foo\" />" + " <state id=\"bar\" />" + " <transition target=\"foo bar\" />" + " </state>" + "</scxml>"; + + std::set<std::string> issueLocations = issueLocationsForXML(xml); + assert(issueLocations.find("//state[@id=\"start\"]") != issueLocations.end()); + assert(issueLocations.find("//state[@id=\"start\"]/transition[1]") != issueLocations.end()); + assert(issueLocations.size() == 2); + } + + if (1) { + // attribute constraints + + { + // initial attribute and <initial> child + const char* xml = + "<scxml datamodel=\"ecmascript\">" + " <state id=\"start\" initial=\"foo\">" + " <initial>" + " <transition target=\"foo\" />" + " </initial>" + " <state id=\"foo\" />" + " </state>" + "</scxml>"; + + std::set<std::string> issueLocations = issueLocationsForXML(xml); + assert(issueLocations.find("//state[@id=\"start\"]") != issueLocations.end()); + assert(issueLocations.size() == 1); + } + + { + // initial attribute with atomic state + const char* xml = + "<scxml datamodel=\"ecmascript\">" + " <state id=\"start\" initial=\"\" />" + "</scxml>"; + + std::set<std::string> issueLocations = issueLocationsForXML(xml); + assert(issueLocations.find("//state[@id=\"start\"]") != issueLocations.end()); + assert(issueLocations.size() == 1); + } + + { + // initial child with atomic state + const char* xml = + "<scxml datamodel=\"ecmascript\">" + " <state id=\"start\">" + " <initial>" + " <transition target=\"start\" />" + " </initial>" + " </state>" + "</scxml>"; + + std::set<std::string> issueLocations = issueLocationsForXML(xml); + assert(issueLocations.find("//state[@id=\"start\"]") != issueLocations.end()); + assert(issueLocations.size() == 2); // also invalid non-child target state in initial + } + + // combinations of namelist, content and param + { + // send with content and namelist, not allowed + const char* xml = + "<scxml datamodel=\"ecmascript\">" + " <state id=\"start\">" + " <onentry>" + " <send target=\"#_external\" namelist=\"var1\">" + " <content>Foo!</content>" + " </send>" + " </onentry>" + " </state>" + "</scxml>"; + + std::set<std::string> issueLocations = issueLocationsForXML(xml); + assert(issueLocations.find("//state[@id=\"start\"]/onentry[1]/send[1]") != issueLocations.end()); + assert(issueLocations.size() == 1); + } + + { + // send with content and params, not allowed + const char* xml = + "<scxml datamodel=\"ecmascript\">" + " <state id=\"start\">" + " <onentry>" + " <send target=\"#_external\">" + " <param name=\"foo\" expr=\"3\" />" + " <content>Foo!</content>" + " </send>" + " </onentry>" + " </state>" + "</scxml>"; + + std::set<std::string> issueLocations = issueLocationsForXML(xml); + assert(issueLocations.find("//state[@id=\"start\"]/onentry[1]/send[1]") != issueLocations.end()); + assert(issueLocations.size() == 1); + } + + { + // send with params and namelist, perfectly acceptable + const char* xml = + "<scxml datamodel=\"ecmascript\">" + " <state id=\"start\">" + " <onentry>" + " <send target=\"#_external\" namelist=\"foo\">" + " <param name=\"foo\" expr=\"3\" />" + " </send>" + " </onentry>" + " </state>" + "</scxml>"; + + std::set<std::string> issueLocations = issueLocationsForXML(xml); + assert(issueLocations.size() == 0); + } + + { + // invoke with content and src, not allowed + const char* xml = + "<scxml datamodel=\"ecmascript\">" + " <state id=\"start\">" + " <invoke type=\"scxml\" src=\"var1\">" + " <content>Foo!</content>" + " </invoke>" + " </state>" + "</scxml>"; + + std::set<std::string> issueLocations = issueLocationsForXML(xml); + assert(issueLocations.find("//state[@id=\"start\"]/invoke[1]") != issueLocations.end()); + assert(issueLocations.size() == 1); + } + + { + // invoke with namelist and param, not allowed + const char* xml = + "<scxml datamodel=\"ecmascript\">" + " <state id=\"start\">" + " <invoke type=\"scxml\" namelist=\"var1\">" + " <param name=\"foo\" expr=\"3\" />" + " </invoke>" + " </state>" + "</scxml>"; + + std::set<std::string> issueLocations = issueLocationsForXML(xml); + assert(issueLocations.find("//state[@id=\"start\"]/invoke[1]") != issueLocations.end()); + assert(issueLocations.size() == 1); + } + + { + // invoke with param and content, perfectly acceptable + const char* xml = + "<scxml datamodel=\"ecmascript\">" + " <state id=\"start\">" + " <invoke type=\"scxml\">" + " <param name=\"foo\" expr=\"3\" />" + " <content>Foo!</content>" + " </invoke>" + " </state>" + "</scxml>"; + + std::set<std::string> issueLocations = issueLocationsForXML(xml); + assert(issueLocations.size() == 0); + } + + { + // invoke with namelist and content, perfectly acceptable + const char* xml = + "<scxml datamodel=\"ecmascript\">" + " <state id=\"start\">" + " <invoke type=\"scxml\" namelist=\"var1\">" + " <content>Foo!</content>" + " </invoke>" + " </state>" + "</scxml>"; + + std::set<std::string> issueLocations = issueLocationsForXML(xml); + assert(issueLocations.size() == 0); + } + + { + // donedata with content and param, not allowed + const char* xml = + "<scxml datamodel=\"ecmascript\">" + " <state id=\"start\">" + " <donedata>" + " <param name=\"foo\" expr=\"3\" />" + " <content>Foo!</content>" + " </donedata>" + " </state>" + "</scxml>"; + + std::set<std::string> issueLocations = issueLocationsForXML(xml); + assert(issueLocations.find("//state[@id=\"start\"]/donedata[1]") != issueLocations.end()); + assert(issueLocations.size() == 1); + } + + + } + + if (1) { // Transition can never be optimally enabled (conditionless, eventless) @@ -433,204 +433,204 @@ int main(int argc, char** argv) { assert(issueLocations.size() == 1); } - if (1) { - // Initial attribute with target outside of children - - const char* xml = - "<scxml datamodel=\"ecmascript\">" - " <state id=\"start\" initial=\"foo done\">" - " <state id=\"foo\" />" - " </state>" - " <final id=\"done\" />" - "</scxml>"; - - std::set<std::string> issueLocations = issueLocationsForXML(xml); - assert(issueLocations.find("//state[@id=\"start\"]") != issueLocations.end()); - assert(issueLocations.size() == 1); - } - - if (1) { - // Initial transition with target outside of children - - const char* xml = - "<scxml datamodel=\"ecmascript\">" - " <state id=\"start\">" - " <initial>" - " <transition target=\"foo done\" />" - " </initial>" - " <state id=\"foo\" />" - " </state>" - " <final id=\"done\" />" - "</scxml>"; - - std::set<std::string> issueLocations = issueLocationsForXML(xml); - assert(issueLocations.find("//state[@id=\"start\"]/initial[1]/transition[1]") != issueLocations.end()); - assert(issueLocations.size() == 1); - } - - if (1) { - // Initial history transition with target outside of children - - const char* xml = - "<scxml datamodel=\"ecmascript\">" - " <state id=\"start\" initial=\"bar\">" - " <history id=\"bar\">" - " <transition target=\"foo done\" />" - " </history>" - " <state id=\"foo\">" - " <transition target=\"baz\" />" - " </state>" - " <state id=\"baz\" />" - " </state>" - " <final id=\"done\" />" - "</scxml>"; - - std::set<std::string> issueLocations = issueLocationsForXML(xml); - assert(issueLocations.find("//history[@id=\"bar\"]/transition[1]") != issueLocations.end()); - assert(issueLocations.size() == 1); - } - - if (1) { - // Initial transition with target outside of children - - const char* xml = - "<scxml datamodel=\"ecmascript\">" - " <state id=\"start\">" - " <initial>" - " <transition target=\"foo done\" />" - " </initial>" - " <state id=\"foo\" />" - " </state>" - " <final id=\"done\" />" - "</scxml>"; - - std::set<std::string> issueLocations = issueLocationsForXML(xml); - assert(issueLocations.find("//state[@id=\"start\"]/initial[1]/transition[1]") != issueLocations.end()); - assert(issueLocations.size() == 1); - } + if (1) { + // Initial attribute with target outside of children + + const char* xml = + "<scxml datamodel=\"ecmascript\">" + " <state id=\"start\" initial=\"foo done\">" + " <state id=\"foo\" />" + " </state>" + " <final id=\"done\" />" + "</scxml>"; + + std::set<std::string> issueLocations = issueLocationsForXML(xml); + assert(issueLocations.find("//state[@id=\"start\"]") != issueLocations.end()); + assert(issueLocations.size() == 1); + } + + if (1) { + // Initial transition with target outside of children + + const char* xml = + "<scxml datamodel=\"ecmascript\">" + " <state id=\"start\">" + " <initial>" + " <transition target=\"foo done\" />" + " </initial>" + " <state id=\"foo\" />" + " </state>" + " <final id=\"done\" />" + "</scxml>"; + + std::set<std::string> issueLocations = issueLocationsForXML(xml); + assert(issueLocations.find("//state[@id=\"start\"]/initial[1]/transition[1]") != issueLocations.end()); + assert(issueLocations.size() == 1); + } + + if (1) { + // Initial history transition with target outside of children + + const char* xml = + "<scxml datamodel=\"ecmascript\">" + " <state id=\"start\" initial=\"bar\">" + " <history id=\"bar\">" + " <transition target=\"foo done\" />" + " </history>" + " <state id=\"foo\">" + " <transition target=\"baz\" />" + " </state>" + " <state id=\"baz\" />" + " </state>" + " <final id=\"done\" />" + "</scxml>"; + + std::set<std::string> issueLocations = issueLocationsForXML(xml); + assert(issueLocations.find("//history[@id=\"bar\"]/transition[1]") != issueLocations.end()); + assert(issueLocations.size() == 1); + } + + if (1) { + // Initial transition with target outside of children + + const char* xml = + "<scxml datamodel=\"ecmascript\">" + " <state id=\"start\">" + " <initial>" + " <transition target=\"foo done\" />" + " </initial>" + " <state id=\"foo\" />" + " </state>" + " <final id=\"done\" />" + "</scxml>"; + + std::set<std::string> issueLocations = issueLocationsForXML(xml); + assert(issueLocations.find("//state[@id=\"start\"]/initial[1]/transition[1]") != issueLocations.end()); + assert(issueLocations.size() == 1); + } if (1) { // Initial transition with event - const char* xml = - "<scxml datamodel=\"ecmascript\">" - " <state id=\"start\">" - " <initial>" - " <transition event=\"e.foo\" target=\"foo\" />" - " </initial>" - " <state id=\"foo\" />" - " <transition event=\"e.bar\" target=\"done\" />" - " </state>" - " <final id=\"done\" />" - "</scxml>"; + const char* xml = + "<scxml datamodel=\"ecmascript\">" + " <state id=\"start\">" + " <initial>" + " <transition event=\"e.foo\" target=\"foo\" />" + " </initial>" + " <state id=\"foo\" />" + " <transition event=\"e.bar\" target=\"done\" />" + " </state>" + " <final id=\"done\" />" + "</scxml>"; std::set<std::string> issueLocations = issueLocationsForXML(xml); - assert(issueLocations.find("//state[@id=\"start\"]/initial[1]/transition[1]") != issueLocations.end()); + assert(issueLocations.find("//state[@id=\"start\"]/initial[1]/transition[1]") != issueLocations.end()); assert(issueLocations.size() == 1); } - if (1) { - // Initial transition with condition - const char* xml = - "<scxml datamodel=\"ecmascript\">" - " <state id=\"start\">" - " <initial>" - " <transition cond=\"true\" target=\"foo\" />" - " </initial>" - " <state id=\"foo\" />" - " <transition event=\"e.bar\" target=\"done\" />" - " </state>" - " <final id=\"done\" />" - "</scxml>"; - - std::set<std::string> issueLocations = issueLocationsForXML(xml); - assert(issueLocations.find("//state[@id=\"start\"]/initial[1]/transition[1]") != issueLocations.end()); - assert(issueLocations.size() == 1); - } - - if (1) { - // Initial with multiple transitions - const char* xml = - "<scxml datamodel=\"ecmascript\">" - " <state id=\"start\">" - " <initial>" - " <transition target=\"foo\" />" - " <transition target=\"foo\" />" - " </initial>" - " <state id=\"foo\" />" - " <transition event=\"e.bar\" target=\"done\" />" - " </state>" - " <final id=\"done\" />" - "</scxml>"; - - std::set<std::string> issueLocations = issueLocationsForXML(xml); - assert(issueLocations.find("//state[@id=\"start\"]/initial[1]") != issueLocations.end()); - assert(issueLocations.size() == 1); - } - - if (1) { - // Initial with no transitions - const char* xml = - "<scxml datamodel=\"ecmascript\">" - " <state id=\"start\">" - " <initial />" - " <state id=\"foo\" />" - " <transition event=\"e.bar\" target=\"done\" />" - " </state>" - " <final id=\"done\" />" - "</scxml>"; - - std::set<std::string> issueLocations = issueLocationsForXML(xml); - assert(issueLocations.find("//state[@id=\"start\"]/initial[1]") != issueLocations.end()); - assert(issueLocations.size() == 1); - } - - if (1) { - // History transition with event - const char* xml = - "<scxml datamodel=\"ecmascript\">" - " <state id=\"start\" initial=\"bar\">" - " <history id=\"bar\">" - " <transition event=\"e.foo\" target=\"foo\" />" - " </history>" - " <state id=\"foo\">" - " <state id=\"foo.s1\">" - " <transition target=\"foo.s2\" />" - " </state>" - " <state id=\"foo.s2\" />" - " </state>" - " <transition event=\"e.bar\" target=\"done\" />" - " </state>" - " <final id=\"done\" />" - "</scxml>"; - - std::set<std::string> issueLocations = issueLocationsForXML(xml); - assert(issueLocations.find("//history[@id=\"bar\"]/transition[1]") != issueLocations.end()); - assert(issueLocations.size() == 1); - } - - if (1) { - // History transition with condition - const char* xml = - "<scxml datamodel=\"ecmascript\">" - " <state id=\"start\" initial=\"bar\">" - " <history id=\"bar\">" - " <transition cond=\"false\" target=\"foo\" />" - " </history>" - " <state id=\"foo\">" - " <state id=\"foo.s1\">" - " <transition target=\"foo.s2\" />" - " </state>" - " <state id=\"foo.s2\" />" - " </state>" - " <transition event=\"e.bar\" target=\"done\" />" - " </state>" - " <final id=\"done\" />" - "</scxml>"; - - std::set<std::string> issueLocations = issueLocationsForXML(xml); - assert(issueLocations.find("//history[@id=\"bar\"]/transition[1]") != issueLocations.end()); - assert(issueLocations.size() == 1); - } + if (1) { + // Initial transition with condition + const char* xml = + "<scxml datamodel=\"ecmascript\">" + " <state id=\"start\">" + " <initial>" + " <transition cond=\"true\" target=\"foo\" />" + " </initial>" + " <state id=\"foo\" />" + " <transition event=\"e.bar\" target=\"done\" />" + " </state>" + " <final id=\"done\" />" + "</scxml>"; + + std::set<std::string> issueLocations = issueLocationsForXML(xml); + assert(issueLocations.find("//state[@id=\"start\"]/initial[1]/transition[1]") != issueLocations.end()); + assert(issueLocations.size() == 1); + } + + if (1) { + // Initial with multiple transitions + const char* xml = + "<scxml datamodel=\"ecmascript\">" + " <state id=\"start\">" + " <initial>" + " <transition target=\"foo\" />" + " <transition target=\"foo\" />" + " </initial>" + " <state id=\"foo\" />" + " <transition event=\"e.bar\" target=\"done\" />" + " </state>" + " <final id=\"done\" />" + "</scxml>"; + + std::set<std::string> issueLocations = issueLocationsForXML(xml); + assert(issueLocations.find("//state[@id=\"start\"]/initial[1]") != issueLocations.end()); + assert(issueLocations.size() == 1); + } + + if (1) { + // Initial with no transitions + const char* xml = + "<scxml datamodel=\"ecmascript\">" + " <state id=\"start\">" + " <initial />" + " <state id=\"foo\" />" + " <transition event=\"e.bar\" target=\"done\" />" + " </state>" + " <final id=\"done\" />" + "</scxml>"; + + std::set<std::string> issueLocations = issueLocationsForXML(xml); + assert(issueLocations.find("//state[@id=\"start\"]/initial[1]") != issueLocations.end()); + assert(issueLocations.size() == 1); + } + + if (1) { + // History transition with event + const char* xml = + "<scxml datamodel=\"ecmascript\">" + " <state id=\"start\" initial=\"bar\">" + " <history id=\"bar\">" + " <transition event=\"e.foo\" target=\"foo\" />" + " </history>" + " <state id=\"foo\">" + " <state id=\"foo.s1\">" + " <transition target=\"foo.s2\" />" + " </state>" + " <state id=\"foo.s2\" />" + " </state>" + " <transition event=\"e.bar\" target=\"done\" />" + " </state>" + " <final id=\"done\" />" + "</scxml>"; + + std::set<std::string> issueLocations = issueLocationsForXML(xml); + assert(issueLocations.find("//history[@id=\"bar\"]/transition[1]") != issueLocations.end()); + assert(issueLocations.size() == 1); + } + + if (1) { + // History transition with condition + const char* xml = + "<scxml datamodel=\"ecmascript\">" + " <state id=\"start\" initial=\"bar\">" + " <history id=\"bar\">" + " <transition cond=\"false\" target=\"foo\" />" + " </history>" + " <state id=\"foo\">" + " <state id=\"foo.s1\">" + " <transition target=\"foo.s2\" />" + " </state>" + " <state id=\"foo.s2\" />" + " </state>" + " <transition event=\"e.bar\" target=\"done\" />" + " </state>" + " <final id=\"done\" />" + "</scxml>"; + + std::set<std::string> issueLocations = issueLocationsForXML(xml); + assert(issueLocations.find("//history[@id=\"bar\"]/transition[1]") != issueLocations.end()); + assert(issueLocations.size() == 1); + } if (1) { // Send to unknown IO Processor @@ -730,9 +730,9 @@ int main(int argc, char** argv) { " <send>" " <param expr=\"%2345\" />" " </send>" - " <send>" - " <content expr=\"%2345\" />" - " </send>" + " <send>" + " <content expr=\"%2345\" />" + " </send>" " </onentry>" " </state>" "</scxml>"; @@ -742,7 +742,7 @@ int main(int argc, char** argv) { assert(issueLocations.find("//data[@id=\"foo\"]") != issueLocations.end()); assert(issueLocations.find("//state[@id=\"start\"]/onentry[1]/assign[1]") != issueLocations.end()); assert(issueLocations.find("//state[@id=\"start\"]/onentry[1]/send[1]/param[1]") != issueLocations.end()); - assert(issueLocations.find("//state[@id=\"start\"]/onentry[1]/send[2]/content[1]") != issueLocations.end()); + assert(issueLocations.find("//state[@id=\"start\"]/onentry[1]/send[2]/content[1]") != issueLocations.end()); assert(issueLocations.size() == 5); } diff --git a/test/src/test-misc.cpp b/test/src/test-misc.cpp index 6259d57..504b6a6 100644 --- a/test/src/test-misc.cpp +++ b/test/src/test-misc.cpp @@ -10,15 +10,15 @@ using namespace uscxml; Timer t1; bool testTimers() { - { - Measurement m(&t1); - tthread::this_thread::sleep_for(tthread::chrono::milliseconds(1000)); - } - std::cout << t1.elapsed << std::endl; - return true; + { + Measurement m(&t1); + tthread::this_thread::sleep_for(tthread::chrono::milliseconds(1000)); + } + std::cout << t1.elapsed << std::endl; + return true; } int main(int argc, char** argv) { - testTimers(); - return 0; + testTimers(); + return 0; }
\ No newline at end of file diff --git a/test/src/test-promela-parser.cpp b/test/src/test-promela-parser.cpp index 8c8f2b4..cab19ab 100644 --- a/test/src/test-promela-parser.cpp +++ b/test/src/test-promela-parser.cpp @@ -18,7 +18,7 @@ using namespace Arabica::DOM; extern int promela_debug; void testInlinePromela() { - + DOMImplementation<std::string> domFactory = Arabica::SimpleDOM::DOMImplementation<std::string>::getDOMImplementation(); Document<std::string> document = domFactory.createDocument("", "", 0); @@ -38,7 +38,7 @@ void testInlinePromela() { promela-code\n \ This is foo!\ "; - + Comment<std::string> comment = document.createComment(test); PromelaInline inl(comment); assert(inl.type == PromelaInline::PROMELA_CODE); @@ -50,26 +50,26 @@ void testInlinePromela() { promela-event\n \ [{\"name\": \"e1\", \"data\": { \"foo\": \"some string\" }}, \ {\"name\": \"e1\", \"data\": { \"bar\": 12 }}]"; - + Comment<std::string> comment = document.createComment(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.getDocument().getDocumentElement()); - + assert(inls.getAllOfType(PromelaInline::PROMELA_EVENT_ONLY).size() == 1); assert(inls.getAllOfType(PromelaInline::PROMELA_EVENT_ALL_BUT).size() == 1); interpreter.getImpl()->getState("s0"); } - + #if 0 { std::string test = "\ @@ -80,8 +80,8 @@ void testInlinePromela() { assert(prmInls.nrAcceptLabels == 0 && prmInls.nrCodes == 1 && prmInls.nrEventSources == 0 && - prmInls.nrEndLabels == 0 && - prmInls.nrAcceptLabels == 0 && + prmInls.nrEndLabels == 0 && + prmInls.nrAcceptLabels == 0 && prmInls.nrProgressLabels == 0); assert(prmInls.code.size() == 1); assert(prmInls.code.front().type == PromelaInline::PROMELA_CODE); @@ -191,13 +191,13 @@ void testInlinePromela() { "; PromelaInlines prmInls = PromelaInlines::fromString(test); assert(prmInls.nrAcceptLabels == 0 && - prmInls.nrCodes == 0 && - prmInls.nrEventSources == 1 && - prmInls.nrEndLabels == 0 && - prmInls.nrProgressLabels == 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); @@ -212,10 +212,10 @@ void testInlinePromela() { "; PromelaInlines prmInls = PromelaInlines::fromString(test); assert(prmInls.nrAcceptLabels == 0 && - prmInls.nrCodes == 0 && - prmInls.nrEventSources == 1 && - prmInls.nrEndLabels == 0 && - prmInls.nrProgressLabels == 1); + 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); @@ -269,7 +269,7 @@ void testPromelaParser() { 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);"); diff --git a/test/src/test-url.cpp b/test/src/test-url.cpp index 1ebcac3..d4aa0c0 100644 --- a/test/src/test-url.cpp +++ b/test/src/test-url.cpp @@ -66,7 +66,7 @@ void testFileURLs() { // absURLs.push_back(URL("/Users/sradomski/Desktop/"));
// absURLs.push_back(URL("/Users/sradomski/Desktop/foo.txt"));
}
-
+
std::list<URL> absWithHostURLs;
{
absWithHostURLs.push_back(URL("file://hostname/"));
@@ -82,17 +82,17 @@ void testFileURLs() { }
// relative URLs
std::list<URL> relURLs;
-
+
{
relURLs.push_back(URL("file"));
relURLs.push_back(URL("file:"));
relURLs.push_back(URL("file://"));
-
+
// platform specific
relURLs.push_back(URL("file:Macintosh%20HD/fileURLs/text.txt"));
relURLs.push_back(URL("file:fileURLs/text.txt"));
relURLs.push_back(URL("file:Document/Text.foo"));
-
+
// usual filesystem paths
relURLs.push_back(URL("Users\\sradomski\\Desktop\\foo.txt"));
relURLs.push_back(URL("Document\\Some Spaces\\index.txt"));
@@ -111,7 +111,7 @@ void testFileURLs() { for (std::list<URL>::iterator relIter = relURLs.begin(); relIter != relURLs.end(); relIter++) {
assert(!relIter->isAbsolute());
}
-
+
for (std::list<URL>::iterator absIter = absURLs.begin(); absIter != absURLs.end(); absIter++) {
for (std::list<URL>::iterator relIter = relURLs.begin(); relIter != relURLs.end(); relIter++) {
URL relURL(*relIter);
@@ -265,7 +265,7 @@ int main(int argc, char** argv) { content << url;
}
#endif
-
+
{
URL url("test/index.html");
assert(iequals(url.scheme(), ""));
diff --git a/test/src/test-w3c.cpp b/test/src/test-w3c.cpp index 2c2f4da..3de8e4d 100644 --- a/test/src/test-w3c.cpp +++ b/test/src/test-w3c.cpp @@ -36,39 +36,39 @@ int retCode = EXIT_FAILURE; uscxml::Interpreter interpreter; void printUsageAndExit(const char* progName) { - // remove path from program name - std::string progStr(progName); - if (progStr.find_last_of(PATH_SEPERATOR) != std::string::npos) { - progStr = progStr.substr(progStr.find_last_of(PATH_SEPERATOR) + 1, progStr.length() - (progStr.find_last_of(PATH_SEPERATOR) + 1)); - } - - printf("%s version " USCXML_VERSION " (" CMAKE_BUILD_TYPE " build - " CMAKE_COMPILER_STRING ")\n", progStr.c_str()); - printf("Usage\n"); - printf("\t%s", progStr.c_str()); - printf(" [-f] [-dN] [-bN]"); + // remove path from program name + std::string progStr(progName); + if (progStr.find_last_of(PATH_SEPERATOR) != std::string::npos) { + progStr = progStr.substr(progStr.find_last_of(PATH_SEPERATOR) + 1, progStr.length() - (progStr.find_last_of(PATH_SEPERATOR) + 1)); + } + + printf("%s version " USCXML_VERSION " (" CMAKE_BUILD_TYPE " build - " CMAKE_COMPILER_STRING ")\n", progStr.c_str()); + printf("Usage\n"); + printf("\t%s", progStr.c_str()); + printf(" [-f] [-dN] [-bN]"); #ifdef BUILD_AS_PLUGINS - printf(" [-p pluginPath]"); + printf(" [-p pluginPath]"); #endif - printf(" URL"); - printf("\n"); - printf("Options\n"); - printf("\t-f : flatten to SCXML state-machine\n"); - printf("\t-d FACTOR : delay factor\n"); - printf("\t-b ITERATIONS : benchmark with number of runs\n"); - printf("\n"); - exit(1); + printf(" URL"); + printf("\n"); + printf("Options\n"); + printf("\t-f : flatten to SCXML state-machine\n"); + printf("\t-d FACTOR : delay factor\n"); + printf("\t-b ITERATIONS : benchmark with number of runs\n"); + printf("\n"); + exit(1); } class W3CStatusMonitor : public uscxml::InterpreterMonitor { -void beforeCompletion(uscxml::Interpreter tmp) { - if (interpreter.getConfiguration().size() == 1 && interpreter.isInState("pass")) { - std::cout << "TEST SUCCEEDED" << std::endl; - retCode = EXIT_SUCCESS; - return; + void beforeCompletion(uscxml::Interpreter tmp) { + if (interpreter.getConfiguration().size() == 1 && interpreter.isInState("pass")) { + std::cout << "TEST SUCCEEDED" << std::endl; + retCode = EXIT_SUCCESS; + return; + } + std::cout << "TEST FAILED" << std::endl; } - std::cout << "TEST FAILED" << std::endl; -} }; int main(int argc, char** argv) { @@ -103,22 +103,22 @@ int main(int argc, char** argv) { case 'd': delayFactor = strTo<double>(optarg); break; - case 'b': - benchmarkRuns = strTo<size_t>(optarg); - break; + case 'b': + benchmarkRuns = strTo<size_t>(optarg); + break; default: break; } } - - const char* envBenchmarkRuns = getenv("USCXML_BENCHMARK_ITERATIONS"); - if (envBenchmarkRuns != NULL) { - benchmarkRuns = strTo<size_t>(envBenchmarkRuns); - } - + + const char* envBenchmarkRuns = getenv("USCXML_BENCHMARK_ITERATIONS"); + if (envBenchmarkRuns != NULL) { + benchmarkRuns = strTo<size_t>(envBenchmarkRuns); + } + documentURI = argv[optind]; - LOG(INFO) << "Processing " << documentURI << (withFlattening ? " FSM converted" : "") << (delayFactor ? "" : " with delays *= " + toStr(delayFactor)) << (benchmarkRuns > 0 ? " for " + toStr(benchmarkRuns) + " benchmarks" : ""); + LOG(INFO) << "Processing " << documentURI << (withFlattening ? " FSM converted" : "") << (delayFactor ? "" : " with delays *= " + toStr(delayFactor)) << (benchmarkRuns > 0 ? " for " + toStr(benchmarkRuns) + " benchmarks" : ""); if (withFlattening) { interpreter = Interpreter::fromURL(documentURI); Transformer flattener = ChartToFlatSCXML::transform(interpreter); @@ -127,7 +127,7 @@ int main(int argc, char** argv) { } else { interpreter = Interpreter::fromURL(documentURI); } - + if (delayFactor != 1) { Arabica::DOM::Document<std::string> document = interpreter.getDocument(); Arabica::DOM::Element<std::string> root = document.getDocumentElement(); @@ -159,53 +159,53 @@ int main(int argc, char** argv) { } if (interpreter) { - W3CStatusMonitor* vm = new W3CStatusMonitor(); - interpreter.addMonitor(vm); + W3CStatusMonitor* vm = new W3CStatusMonitor(); + interpreter.addMonitor(vm); - if (benchmarkRuns > 0) { - LOG(INFO) << "Benchmarking " << documentURI << (withFlattening ? " FSM converted" : "") << (delayFactor ? "" : " with delays *= " + toStr(delayFactor)); + if (benchmarkRuns > 0) { + LOG(INFO) << "Benchmarking " << documentURI << (withFlattening ? " FSM converted" : "") << (delayFactor ? "" : " with delays *= " + toStr(delayFactor)); - InterpreterState state = interpreter.getState(); + InterpreterState state = interpreter.getState(); - double avg = 0; + double avg = 0; #ifdef BUILD_PROFILING - double avgDm = 0; - double avgStep = 0; + double avgDm = 0; + double avgStep = 0; #endif - size_t remainingRuns = benchmarkRuns; - uint64_t start = tthread::chrono::system_clock::now(); - - while(remainingRuns-- > 0) { - Timer t; - t.start(); - for(;;) { - state = interpreter.step(true); - if (state == USCXML_FINISHED) { + size_t remainingRuns = benchmarkRuns; + uint64_t start = tthread::chrono::system_clock::now(); + + while(remainingRuns-- > 0) { + Timer t; + t.start(); + for(;;) { + state = interpreter.step(true); + if (state == USCXML_FINISHED) { #ifdef BUILD_PROFILING - avgDm += interpreter.getDataModel().timer.elapsed; - interpreter.getDataModel().timer.reset(); - avgStep += interpreter.timer.elapsed; + avgDm += interpreter.getDataModel().timer.elapsed; + interpreter.getDataModel().timer.reset(); + avgStep += interpreter.timer.elapsed; #endif - } - if (state < 0) - break; - } - t.stop(); - avg += t.elapsed; - interpreter.reset(); - } - uint64_t totalDuration = tthread::chrono::system_clock::now() - start; - std::cout << benchmarkRuns << " iterations in " << totalDuration << " ms" << std::endl; - std::cout << (avg * 1000.0) / (double)benchmarkRuns << " ms on average" << std::endl; + } + if (state < 0) + break; + } + t.stop(); + avg += t.elapsed; + interpreter.reset(); + } + uint64_t totalDuration = tthread::chrono::system_clock::now() - start; + std::cout << benchmarkRuns << " iterations in " << totalDuration << " ms" << std::endl; + std::cout << (avg * 1000.0) / (double)benchmarkRuns << " ms on average" << std::endl; #ifdef BUILD_PROFILING - std::cout << (avgDm * 1000.0) / (double)benchmarkRuns << " ms in datamodel" << std::endl; - std::cout << (avgStep * 1000.0) / (double)benchmarkRuns << " ms in microsteps" << std::endl; + std::cout << (avgDm * 1000.0) / (double)benchmarkRuns << " ms in datamodel" << std::endl; + std::cout << (avgStep * 1000.0) / (double)benchmarkRuns << " ms in microsteps" << std::endl; #endif - } else { - interpreter.start(); - while(interpreter.runOnMainThread(25)); - } + } else { + interpreter.start(); + while(interpreter.runOnMainThread(25)); + } } } catch(Event e) { std::cout << e << std::endl; |