diff options
Diffstat (limited to 'src/uscxml')
56 files changed, 5081 insertions, 3848 deletions
diff --git a/src/uscxml/DOMUtils.cpp b/src/uscxml/DOMUtils.cpp index 1115c1d..0a6e350 100644 --- a/src/uscxml/DOMUtils.cpp +++ b/src/uscxml/DOMUtils.cpp @@ -25,22 +25,22 @@ namespace uscxml { - + bool DOMUtils::attributeIsTrue(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")); } std::string DOMUtils::xPathForNode(const Arabica::DOM::Node<std::string>& node, const std::string& ns) { std::string xPath; std::string nsPrefix; - + if (ns.size() > 0) { nsPrefix = ns + ":"; } - + if (!node || node.getNodeType() != Arabica::DOM::Node_base::ELEMENT_NODE) return xPath; diff --git a/src/uscxml/Factory.cpp b/src/uscxml/Factory.cpp index 5f3d172..289c2bb 100644 --- a/src/uscxml/Factory.cpp +++ b/src/uscxml/Factory.cpp @@ -623,7 +623,7 @@ void DataModelImpl::throwErrorPlatform(const std::string& cause) { throw exc; } - + Factory* Factory::_instance = NULL; std::string Factory::pluginPath; }
\ No newline at end of file diff --git a/src/uscxml/Factory.h b/src/uscxml/Factory.h index 14325f1..02ce6b8 100644 --- a/src/uscxml/Factory.h +++ b/src/uscxml/Factory.h @@ -126,7 +126,7 @@ public: void setElement(const Arabica::DOM::Element<std::string>& element) { _element = element; } - + Arabica::DOM::Element<std::string> getElement() { return _element; } @@ -181,7 +181,7 @@ public: void setElement(const Arabica::DOM::Element<std::string>& element) { _impl->setElement(element); } - + Arabica::DOM::Element<std::string> getElement() { return _impl->getElement(); } @@ -316,11 +316,13 @@ public: _interpreter = interpreter; } - virtual std::string andExpressions(std::list<std::string>) { return ""; } - + virtual std::string andExpressions(std::list<std::string>) { + return ""; + } + static void throwErrorExecution(const std::string& cause); static void throwErrorPlatform(const std::string& cause); - + // we need it public for various static functions InterpreterImpl* _interpreter; }; diff --git a/src/uscxml/Interpreter.cpp b/src/uscxml/Interpreter.cpp index ee8c7d0..b7de262 100644 --- a/src/uscxml/Interpreter.cpp +++ b/src/uscxml/Interpreter.cpp @@ -236,6 +236,35 @@ DONE_PARSING_CMD: return options; } + +void NameSpaceInfo::init(const std::map<std::string, std::string>& namespaceInfo) { + nsInfo = namespaceInfo; + nsURL = ""; + nsContext = new Arabica::XPath::StandardNamespaceContext<std::string>(); + + std::map<std::string, std::string>::const_iterator nsIter = namespaceInfo.begin(); + while(nsIter != namespaceInfo.end()) { + std::string uri = nsIter->first; + std::string prefix = nsIter->second; + if (iequals(uri, "http://www.w3.org/2005/07/scxml")) { + nsURL = uri; + if (prefix.size() == 0) { + xpathPrefix = "scxml:"; + nsContext->addNamespaceDeclaration(uri, "scxml"); + } else { + xpathPrefix = prefix + ":"; + xmlNSPrefix = xpathPrefix; + nsContext->addNamespaceDeclaration(uri, prefix); + nsToPrefix[uri] = prefix; + } + } else { + nsContext->addNamespaceDeclaration(uri, prefix); + nsToPrefix[uri] = prefix; + } + nsIter++; + } +} + std::map<std::string, boost::weak_ptr<InterpreterImpl> > Interpreter::_instances; tthread::recursive_mutex Interpreter::_instanceMutex; @@ -255,7 +284,6 @@ std::map<std::string, boost::weak_ptr<InterpreterImpl> > Interpreter::getInstanc InterpreterImpl::InterpreterImpl() { _lastRunOnMainThread = 0; - _nsURL = "*"; _thread = NULL; _sendQueue = NULL; _parentQueue = NULL; @@ -274,7 +302,7 @@ InterpreterImpl::InterpreterImpl() { #endif } -Interpreter Interpreter::fromDOM(const Arabica::DOM::Document<std::string>& dom, const std::map<std::string, std::string>& nameSpaceInfo) { +Interpreter Interpreter::fromDOM(const Arabica::DOM::Document<std::string>& dom, const NameSpaceInfo& nameSpaceInfo) { tthread::lock_guard<tthread::recursive_mutex> lock(_instanceMutex); boost::shared_ptr<INTERPRETER_IMPL> interpreterImpl = boost::shared_ptr<INTERPRETER_IMPL>(new INTERPRETER_IMPL); Interpreter interpreter(interpreterImpl); @@ -343,6 +371,7 @@ Interpreter Interpreter::fromURI(const std::string& uri) { Interpreter Interpreter::fromInputSource(Arabica::SAX::InputSource<std::string>& source) { tthread::lock_guard<tthread::recursive_mutex> lock(_instanceMutex); + // remove old instances std::map<std::string, boost::weak_ptr<InterpreterImpl> >::iterator instIter = _instances.begin(); while(instIter != _instances.end()) { if (!instIter->second.lock()) { @@ -370,34 +399,60 @@ Interpreter Interpreter::fromInputSource(Arabica::SAX::InputSource<std::string>& return interpreter; } -void InterpreterImpl::setNameSpaceInfo(const std::map<std::string, std::string> namespaceInfo) { - _nameSpaceInfo = namespaceInfo; - std::map<std::string, std::string>::const_iterator nsIter = namespaceInfo.begin(); - while(nsIter != namespaceInfo.end()) { - std::string uri = nsIter->first; - std::string prefix = nsIter->second; - if (iequals(uri, "http://www.w3.org/2005/07/scxml")) { - _nsURL = uri; - if (prefix.size() == 0) { -// LOG(INFO) << "Mapped default namespace to 'scxml:'"; - _xpathPrefix = "scxml:"; - _nsContext.addNamespaceDeclaration(uri, "scxml"); - _nsToPrefix[uri] = "scxml"; - } else { - _xpathPrefix = prefix + ":"; - _xmlNSPrefix = _xpathPrefix; - _nsContext.addNamespaceDeclaration(uri, prefix); - _nsToPrefix[uri] = prefix; - } +Interpreter Interpreter::fromClone(const Interpreter& other) { + boost::shared_ptr<INTERPRETER_IMPL> interpreterImpl = boost::shared_ptr<INTERPRETER_IMPL>(new INTERPRETER_IMPL); + + other.getImpl()->copyTo(interpreterImpl); + Interpreter interpreter(interpreterImpl); + return interpreter; +} + +void InterpreterImpl::copyTo(InterpreterImpl* other) { + if (getDocument()) { +#if 0 + std::stringstream* ss = new std::stringstream(); + (*ss) << getDocument(); + // we need an auto_ptr for arabica to assume ownership + std::auto_ptr<std::istream> ssPtr(ss); + Arabica::SAX::InputSource<std::string> inputSource; + inputSource.setByteStream(ssPtr); + + NameSpacingParser parser; + if (parser.parse(inputSource) && parser.getDocument() && parser.getDocument().hasChildNodes()) { + other->setNameSpaceInfo(parser.nameSpace); + other->_document = parser.getDocument(); + other->init(); } else { - _nsContext.addNamespaceDeclaration(uri, prefix); - _nsToPrefix[uri] = prefix; + if (parser.errorsReported()) { + LOG(ERROR) << parser.errors(); + } } - nsIter++; + +#else + Arabica::DOM::Document<std::string> clonedDocument; + DOMImplementation<std::string> domFactory = Arabica::SimpleDOM::DOMImplementation<std::string>::getDOMImplementation(); + clonedDocument = domFactory.createDocument(getDocument().getNamespaceURI(), "", 0); + + Node<std::string> child = getDocument().getFirstChild(); + while (child) { + Node<std::string> newNode = clonedDocument.importNode(child, true); + clonedDocument.appendChild(newNode); + child = child.getNextSibling(); + } + + other->_document = clonedDocument; + + other->setNameSpaceInfo(_nsInfo); + other->init(); +#endif } +} +void InterpreterImpl::copyTo(boost::shared_ptr<InterpreterImpl> other) { + copyTo(other.get()); } + void InterpreterImpl::setName(const std::string& name) { if (!_running) { _name = name; @@ -415,7 +470,7 @@ InterpreterImpl::~InterpreterImpl() { Event event; event.name = "unblock.and.die"; receive(event); - + _thread->join(); delete(_thread); } else { @@ -439,7 +494,7 @@ void InterpreterImpl::stop() { _running = false; } - + void InterpreterImpl::run(void* instance) { try { ((InterpreterImpl*)instance)->interpret(); @@ -489,12 +544,18 @@ bool InterpreterImpl::runOnMainThread(int fps, bool blocking) { void InterpreterImpl::init() { if (_document) { - NodeList<std::string> scxmls = _document.getElementsByTagNameNS(_nsURL, "scxml"); + NodeList<std::string> scxmls; + if (_nsInfo.nsURL.size() == 0) { + scxmls = _document.getElementsByTagName("scxml"); + } else { + scxmls = _document.getElementsByTagNameNS(_nsInfo.nsURL, "scxml"); + } if (scxmls.getLength() > 0) { _scxml = (Arabica::DOM::Element<std::string>)scxmls.item(0); // setup xpath and check that it works - _xpath.setNamespaceContext(_nsContext); + if (_nsInfo.nsContext != NULL) + _xpath.setNamespaceContext(*_nsInfo.nsContext); if (_name.length() == 0) _name = (HAS_ATTR(_scxml, "name") ? ATTR(_scxml, "name") : UUID::getUUID()); @@ -574,7 +635,7 @@ void InterpreterImpl::normalize(Arabica::DOM::Element<std::string>& scxml) { // TODO: Resolve XML includes // make sure every state has an id and set isFirstEntry to true (replaced by _alreadyEntered NodeSet) - Arabica::XPath::NodeSet<std::string> states = _xpath.evaluate("//" + _xpathPrefix + "state", _scxml).asNodeSet(); + Arabica::XPath::NodeSet<std::string> states = _xpath.evaluate("//" + _nsInfo.xpathPrefix + "state", _scxml).asNodeSet(); for (int i = 0; i < states.size(); i++) { Arabica::DOM::Element<std::string> stateElem = Arabica::DOM::Element<std::string>(states[i]); // stateElem.setAttribute("isFirstEntry", "true"); @@ -584,7 +645,7 @@ void InterpreterImpl::normalize(Arabica::DOM::Element<std::string>& scxml) { } // make sure every invoke has an idlocation or id - Arabica::XPath::NodeSet<std::string> invokes = _xpath.evaluate("//" + _xpathPrefix + "invoke", _scxml).asNodeSet(); + Arabica::XPath::NodeSet<std::string> invokes = _xpath.evaluate("//" + _nsInfo.xpathPrefix + "invoke", _scxml).asNodeSet(); for (int i = 0; i < invokes.size(); i++) { Arabica::DOM::Element<std::string> invokeElem = Arabica::DOM::Element<std::string>(invokes[i]); if (!invokeElem.hasAttribute("id") && !invokeElem.hasAttribute("idlocation")) { @@ -598,7 +659,7 @@ void InterpreterImpl::normalize(Arabica::DOM::Element<std::string>& scxml) { // } } - Arabica::XPath::NodeSet<std::string> finals = _xpath.evaluate("//" + _xpathPrefix + "final", _scxml).asNodeSet(); + Arabica::XPath::NodeSet<std::string> finals = _xpath.evaluate("//" + _nsInfo.xpathPrefix + "final", _scxml).asNodeSet(); for (int i = 0; i < finals.size(); i++) { Arabica::DOM::Element<std::string> finalElem = Arabica::DOM::Element<std::string>(finals[i]); // finalElem.setAttribute("isFirstEntry", "true"); @@ -607,7 +668,7 @@ void InterpreterImpl::normalize(Arabica::DOM::Element<std::string>& scxml) { } } - Arabica::XPath::NodeSet<std::string> histories = _xpath.evaluate("//" + _xpathPrefix + "history", _scxml).asNodeSet(); + Arabica::XPath::NodeSet<std::string> histories = _xpath.evaluate("//" + _nsInfo.xpathPrefix + "history", _scxml).asNodeSet(); for (int i = 0; i < histories.size(); i++) { Arabica::DOM::Element<std::string> historyElem = Arabica::DOM::Element<std::string>(histories[i]); if (!historyElem.hasAttribute("id")) { @@ -619,16 +680,6 @@ void InterpreterImpl::normalize(Arabica::DOM::Element<std::string>& scxml) { scxml.setAttribute("id", UUID::getUUID()); } - // create a pseudo initial and transition element -#if 0 - Arabica::DOM::Element<std::string> initialState = (Arabica::DOM::Element<std::string>)getInitialState(); - Arabica::DOM::Element<std::string> initialElem = _document.createElement("initial"); - Arabica::DOM::Element<std::string> transitionElem = _document.createElement("transition"); - transitionElem.setAttribute("target", initialState.getAttribute("id")); - initialElem.appendChild(transitionElem); - _scxml.appendChild(initialElem); - std::cout << _scxml <<std::endl; -#endif } void InterpreterImpl::receiveInternal(const Event& event) { @@ -655,12 +706,12 @@ void InterpreterImpl::internalDoneSend(const Arabica::DOM::Node<std::string>& st Arabica::DOM::Element<std::string> parent = (Arabica::DOM::Element<std::string>)stateElem.getParentNode(); Event event; - Arabica::XPath::NodeSet<std::string> doneDatas = filterChildElements(_xmlNSPrefix + "donedata", stateElem); + Arabica::XPath::NodeSet<std::string> doneDatas = filterChildElements(_nsInfo.xmlNSPrefix + "donedata", stateElem); if (doneDatas.size() > 0) { // only process first donedata element Arabica::DOM::Node<std::string> doneData = doneDatas[0]; processParamChilds(doneData, event.params); - Arabica::XPath::NodeSet<std::string> contents = filterChildElements(_xmlNSPrefix + "content", doneDatas[0]); + Arabica::XPath::NodeSet<std::string> contents = filterChildElements(_nsInfo.xmlNSPrefix + "content", doneDatas[0]); if (contents.size() > 1) LOG(ERROR) << "Only a single content element is allowed for send elements - using first one"; if (contents.size() > 0) { @@ -793,7 +844,7 @@ void InterpreterImpl::processDOMorText(const Arabica::DOM::Node<std::string>& el } void InterpreterImpl::processParamChilds(const Arabica::DOM::Node<std::string>& element, std::multimap<std::string, Data>& params) { - NodeSet<std::string> paramElems = filterChildElements(_xmlNSPrefix + "param", element); + NodeSet<std::string> paramElems = filterChildElements(_nsInfo.xmlNSPrefix + "param", element); for (int i = 0; i < paramElems.size(); i++) { try { if (!HAS_ATTR(paramElems[i], "name")) { @@ -953,7 +1004,7 @@ void InterpreterImpl::send(const Arabica::DOM::Node<std::string>& element) { } try { // content - NodeSet<std::string> contents = filterChildElements(_xmlNSPrefix + "content", element); + NodeSet<std::string> contents = filterChildElements(_nsInfo.xmlNSPrefix + "content", element); if (contents.size() > 1) LOG(ERROR) << "Only a single content element is allowed for send elements " << DOMUtils::xPathForNode(element) << " - using first one"; if (contents.size() > 0) { @@ -1095,7 +1146,7 @@ void InterpreterImpl::invoke(const Arabica::DOM::Node<std::string>& element) { // content try { - NodeSet<std::string> contents = filterChildElements(_xmlNSPrefix + "content", element); + NodeSet<std::string> contents = filterChildElements(_nsInfo.xmlNSPrefix + "content", element); if (contents.size() > 1) LOG(ERROR) << "Only a single content element is allowed for send elements - using first one"; if (contents.size() > 0) { @@ -1140,12 +1191,13 @@ void InterpreterImpl::invoke(const Arabica::DOM::Node<std::string>& element) { invoker.setElement(Element<std::string>(element)); _invokers[invokeReq.invokeid] = invoker; try { - + // --- MONITOR: beforeInvoking ------------------------------ for(monIter_t monIter = _monitors.begin(); monIter != _monitors.end(); monIter++) { try { (*monIter)->beforeInvoking(shared_from_this(), Element<std::string>(element), invokeReq.invokeid); - } USCXML_MONITOR_CATCH_BLOCK(beforeInvoking) + } + USCXML_MONITOR_CATCH_BLOCK(beforeInvoking) } invoker.invoke(invokeReq); @@ -1155,7 +1207,8 @@ void InterpreterImpl::invoke(const Arabica::DOM::Node<std::string>& element) { for(monIter_t monIter = _monitors.begin(); monIter != _monitors.end(); monIter++) { try { (*monIter)->afterInvoking(shared_from_this(), Element<std::string>(element), invokeReq.invokeid); - } USCXML_MONITOR_CATCH_BLOCK(afterInvoking) + } + USCXML_MONITOR_CATCH_BLOCK(afterInvoking) } // this is out of draft but so useful to know when an invoker started @@ -1205,12 +1258,13 @@ void InterpreterImpl::cancelInvoke(const Arabica::DOM::Node<std::string>& elemen LOG(ERROR) << "Syntax when removing invoker:" << std::endl << e << std::endl; } } - + // --- MONITOR: beforeUninvoking ------------------------------ for(monIter_t monIter = _monitors.begin(); monIter != _monitors.end(); monIter++) { try { (*monIter)->beforeUninvoking(shared_from_this(), Element<std::string>(element), invokeId); - } USCXML_MONITOR_CATCH_BLOCK(beforeUninvoking) + } + USCXML_MONITOR_CATCH_BLOCK(beforeUninvoking) } _invokers.erase(invokeId); @@ -1219,7 +1273,8 @@ void InterpreterImpl::cancelInvoke(const Arabica::DOM::Node<std::string>& elemen for(monIter_t monIter = _monitors.begin(); monIter != _monitors.end(); monIter++) { try { (*monIter)->afterUninvoking(shared_from_this(), Element<std::string>(element), invokeId); - } USCXML_MONITOR_CATCH_BLOCK(beforeUninvoking) + } + USCXML_MONITOR_CATCH_BLOCK(beforeUninvoking) } } else { @@ -1321,10 +1376,10 @@ void InterpreterImpl::executeContent(const Arabica::DOM::Node<std::string>& cont if (content.getNodeType() != Node_base::ELEMENT_NODE) return; - if (iequals(TAGNAME(content), _xmlNSPrefix + "onentry") || - iequals(TAGNAME(content), _xmlNSPrefix + "onexit") || - iequals(TAGNAME(content), _xmlNSPrefix + "finalize") || - iequals(TAGNAME(content), _xmlNSPrefix + "transition")) { + if (iequals(TAGNAME(content), _nsInfo.xmlNSPrefix + "onentry") || + iequals(TAGNAME(content), _nsInfo.xmlNSPrefix + "onexit") || + iequals(TAGNAME(content), _nsInfo.xmlNSPrefix + "finalize") || + iequals(TAGNAME(content), _nsInfo.xmlNSPrefix + "transition")) { // --- CONVENIENCE LOOP -------------------------- NodeList<std::string> executable = content.getChildNodes(); for (int i = 0; i < executable.getLength(); i++) { @@ -1337,11 +1392,12 @@ void InterpreterImpl::executeContent(const Arabica::DOM::Node<std::string>& cont for(monIter_t monIter = _monitors.begin(); monIter != _monitors.end(); monIter++) { try { (*monIter)->beforeExecutingContent(shared_from_this(), Element<std::string>(content)); - } USCXML_MONITOR_CATCH_BLOCK(beforeExecutingContent) + } + USCXML_MONITOR_CATCH_BLOCK(beforeExecutingContent) } if (false) { - } else if (iequals(TAGNAME(content), _xmlNSPrefix + "raise")) { + } else if (iequals(TAGNAME(content), _nsInfo.xmlNSPrefix + "raise")) { // --- RAISE -------------------------- #if 0 if (HAS_ATTR(content, "event")) { @@ -1354,7 +1410,7 @@ void InterpreterImpl::executeContent(const Arabica::DOM::Node<std::string>& cont try { // content processParamChilds(content, raised.params); - NodeSet<std::string> contents = filterChildElements(_xmlNSPrefix + "content", content); + NodeSet<std::string> contents = filterChildElements(_nsInfo.xmlNSPrefix + "content", content); if (contents.size() > 1) LOG(ERROR) << "Only a single content element is allowed for raise elements " << DOMUtils::xPathForNode(content) << " - using first one"; if (contents.size() > 0) { @@ -1379,7 +1435,7 @@ void InterpreterImpl::executeContent(const Arabica::DOM::Node<std::string>& cont LOG(ERROR) << "Syntax error in send element " << DOMUtils::xPathForNode(content) << " content:" << std::endl << raised << std::endl; return; } - + if (raised.dom) { std::stringstream ss; ss << raised.dom; @@ -1389,7 +1445,7 @@ void InterpreterImpl::executeContent(const Arabica::DOM::Node<std::string>& cont receiveInternal(raised); } #endif - } else if (iequals(TAGNAME(content), _xmlNSPrefix + "if")) { + } else if (iequals(TAGNAME(content), _nsInfo.xmlNSPrefix + "if")) { // --- IF / ELSEIF / ELSE -------------- Arabica::DOM::Element<std::string> ifElem = (Arabica::DOM::Element<std::string>)content; #if 0 @@ -1406,8 +1462,8 @@ void InterpreterImpl::executeContent(const Arabica::DOM::Node<std::string>& cont for (unsigned int i = 0; i < childs.getLength(); i++) { if (childs.item(i).getNodeType() != Node_base::ELEMENT_NODE) continue; - if (iequals(TAGNAME(childs.item(i)), _xmlNSPrefix + "elseif") || - iequals(TAGNAME(childs.item(i)), _xmlNSPrefix + "else")) { + if (iequals(TAGNAME(childs.item(i)), _nsInfo.xmlNSPrefix + "elseif") || + iequals(TAGNAME(childs.item(i)), _nsInfo.xmlNSPrefix + "else")) { if (blockIsTrue) { // last block was true, break here break; @@ -1422,11 +1478,11 @@ void InterpreterImpl::executeContent(const Arabica::DOM::Node<std::string>& cont } } } - } else if (iequals(TAGNAME(content), _xmlNSPrefix + "elseif")) { + } else if (iequals(TAGNAME(content), _nsInfo.xmlNSPrefix + "elseif")) { std::cerr << "Found single elsif to evaluate!" << std::endl; - } else if (iequals(TAGNAME(content), _xmlNSPrefix + "else")) { + } else if (iequals(TAGNAME(content), _nsInfo.xmlNSPrefix + "else")) { std::cerr << "Found single else to evaluate!" << std::endl; - } else if (iequals(TAGNAME(content), _xmlNSPrefix + "foreach")) { + } else if (iequals(TAGNAME(content), _nsInfo.xmlNSPrefix + "foreach")) { // --- FOREACH -------------------------- if (_dataModel) { if (HAS_ATTR(content, "array") && HAS_ATTR(content, "item")) { @@ -1456,7 +1512,7 @@ void InterpreterImpl::executeContent(const Arabica::DOM::Node<std::string>& cont LOG(ERROR) << "Expected array and item attributes with foreach element!" << std::endl; } } - } else if (iequals(TAGNAME(content), _xmlNSPrefix + "log")) { + } else if (iequals(TAGNAME(content), _nsInfo.xmlNSPrefix + "log")) { // --- LOG -------------------------- Arabica::DOM::Element<std::string> logElem = (Arabica::DOM::Element<std::string>)content; if (logElem.hasAttribute("label")) @@ -1470,7 +1526,7 @@ void InterpreterImpl::executeContent(const Arabica::DOM::Node<std::string>& cont if (logElem.hasAttribute("label")) std::cout << std::endl; } - } else if (iequals(TAGNAME(content), _xmlNSPrefix + "assign")) { + } else if (iequals(TAGNAME(content), _nsInfo.xmlNSPrefix + "assign")) { // --- ASSIGN -------------------------- if (_dataModel && HAS_ATTR(content, "location")) { try { @@ -1487,14 +1543,14 @@ void InterpreterImpl::executeContent(const Arabica::DOM::Node<std::string>& cont } CATCH_AND_DISTRIBUTE2("Syntax error in attributes of assign element", content) } - } else if (iequals(TAGNAME(content), _xmlNSPrefix + "validate")) { + } else if (iequals(TAGNAME(content), _nsInfo.xmlNSPrefix + "validate")) { // --- VALIDATE -------------------------- if (_dataModel) { std::string location = (HAS_ATTR(content, "location") ? ATTR(content, "location") : ""); std::string schema = (HAS_ATTR(content, "schema") ? ATTR(content, "schema") : ""); _dataModel.validate(location, schema); } - } else if (iequals(TAGNAME(content), _xmlNSPrefix + "script")) { + } else if (iequals(TAGNAME(content), _nsInfo.xmlNSPrefix + "script")) { // --- SCRIPT -------------------------- if (_dataModel) { if (HAS_ATTR(content, "src")) { @@ -1545,13 +1601,13 @@ void InterpreterImpl::executeContent(const Arabica::DOM::Node<std::string>& cont } } } - } else if (iequals(TAGNAME(content), _xmlNSPrefix + "send")) { + } else if (iequals(TAGNAME(content), _nsInfo.xmlNSPrefix + "send")) { // --- SEND -------------------------- try { send(content); } CATCH_AND_DISTRIBUTE2("Error while sending content", content) - } else if (iequals(TAGNAME(content), _xmlNSPrefix + "cancel")) { + } else if (iequals(TAGNAME(content), _nsInfo.xmlNSPrefix + "cancel")) { // --- CANCEL -------------------------- std::string sendId; try { @@ -1567,7 +1623,7 @@ void InterpreterImpl::executeContent(const Arabica::DOM::Node<std::string>& cont } CATCH_AND_DISTRIBUTE2("Syntax error while executing cancel element", content) - } else if (iequals(TAGNAME(content), _xmlNSPrefix + "invoke")) { + } else if (iequals(TAGNAME(content), _nsInfo.xmlNSPrefix + "invoke")) { // --- INVOKE -------------------------- } else { // --- Custom Executable Content @@ -1593,12 +1649,13 @@ void InterpreterImpl::executeContent(const Arabica::DOM::Node<std::string>& cont } execContent.exitElement(content); } - + // --- MONITOR: afterExecutingContent ------------------------------ for(monIter_t monIter = _monitors.begin(); monIter != _monitors.end(); monIter++) { try { (*monIter)->afterExecutingContent(shared_from_this(), Element<std::string>(content)); - } USCXML_MONITOR_CATCH_BLOCK(afterExecutingContent) + } + USCXML_MONITOR_CATCH_BLOCK(afterExecutingContent) } } @@ -1615,7 +1672,7 @@ void InterpreterImpl::returnDoneEvent(const Arabica::DOM::Node<std::string>& sta bool InterpreterImpl::parentIsScxmlState(const Arabica::DOM::Node<std::string>& state) { Arabica::DOM::Element<std::string> stateElem = (Arabica::DOM::Element<std::string>)state; Arabica::DOM::Element<std::string> parentElem = (Arabica::DOM::Element<std::string>)state.getParentNode(); - if (iequals(TAGNAME(parentElem), _xmlNSPrefix + "scxml")) + if (iequals(TAGNAME(parentElem), _nsInfo.xmlNSPrefix + "scxml")) return true; return false; } @@ -1665,7 +1722,7 @@ Arabica::XPath::NodeSet<std::string> InterpreterImpl::getChildStates(const Arabi } return childs; } - + Arabica::DOM::Node<std::string> InterpreterImpl::getParentState(const Arabica::DOM::Node<std::string>& element) { Arabica::DOM::Node<std::string> parent = element.getParentNode(); while(parent && !isState(parent)) { @@ -1749,22 +1806,22 @@ Arabica::DOM::Node<std::string> InterpreterImpl::getState(const std::string& sta } // first try atomic and compound states - NodeSet<std::string> target = _xpath.evaluate("//" + _xpathPrefix + "state[@id='" + stateId + "']", _scxml).asNodeSet(); + NodeSet<std::string> target = _xpath.evaluate("//" + _nsInfo.xpathPrefix + "state[@id='" + stateId + "']", _scxml).asNodeSet(); if (target.size() > 0) goto FOUND; // now parallel states - target = _xpath.evaluate("//" + _xpathPrefix + "parallel[@id='" + stateId + "']", _scxml).asNodeSet(); + target = _xpath.evaluate("//" + _nsInfo.xpathPrefix + "parallel[@id='" + stateId + "']", _scxml).asNodeSet(); if (target.size() > 0) goto FOUND; // now final states - target = _xpath.evaluate("//" + _xpathPrefix + "final[@id='" + stateId + "']", _scxml).asNodeSet(); + target = _xpath.evaluate("//" + _nsInfo.xpathPrefix + "final[@id='" + stateId + "']", _scxml).asNodeSet(); if (target.size() > 0) goto FOUND; // now history states - target = _xpath.evaluate("//" + _xpathPrefix + "history[@id='" + stateId + "']", _scxml).asNodeSet(); + target = _xpath.evaluate("//" + _nsInfo.xpathPrefix + "history[@id='" + stateId + "']", _scxml).asNodeSet(); if (target.size() > 0) goto FOUND; @@ -1791,15 +1848,15 @@ FOUND: Arabica::XPath::NodeSet<std::string> InterpreterImpl::getAllStates() { NodeSet<std::string> states; - states.push_back(_xpath.evaluate("//" + _xpathPrefix + "state", _scxml).asNodeSet()); - states.push_back(_xpath.evaluate("//" + _xpathPrefix + "parallel", _scxml).asNodeSet()); - states.push_back(_xpath.evaluate("//" + _xpathPrefix + "final", _scxml).asNodeSet()); - states.push_back(_xpath.evaluate("//" + _xpathPrefix + "history", _scxml).asNodeSet()); + states.push_back(_xpath.evaluate("//" + _nsInfo.xpathPrefix + "state", _scxml).asNodeSet()); + states.push_back(_xpath.evaluate("//" + _nsInfo.xpathPrefix + "parallel", _scxml).asNodeSet()); + states.push_back(_xpath.evaluate("//" + _nsInfo.xpathPrefix + "final", _scxml).asNodeSet()); + states.push_back(_xpath.evaluate("//" + _nsInfo.xpathPrefix + "history", _scxml).asNodeSet()); return states; } - + Arabica::DOM::Node<std::string> InterpreterImpl::getSourceState(const Arabica::DOM::Node<std::string>& transition) { - if (iequals(TAGNAME(transition.getParentNode()), _xmlNSPrefix + "initial")) + if (iequals(TAGNAME(transition.getParentNode()), _nsInfo.xmlNSPrefix + "initial")) return transition.getParentNode().getParentNode(); return transition.getParentNode(); } @@ -1829,9 +1886,9 @@ Arabica::XPath::NodeSet<std::string> InterpreterImpl::getInitialStates(Arabica:: } // initial element as child - but not the implicit generated one - NodeSet<std::string> initElems = filterChildElements(_xmlNSPrefix + "initial", state); + NodeSet<std::string> initElems = filterChildElements(_nsInfo.xmlNSPrefix + "initial", state); if(initElems.size() == 1 && !iequals(ATTR(initElems[0], "generated"), "true")) { - NodeSet<std::string> initTrans = filterChildElements(_xmlNSPrefix + "transition", initElems[0]); + NodeSet<std::string> initTrans = filterChildElements(_nsInfo.xmlNSPrefix + "transition", initElems[0]); return getTargetStates(initTrans[0]); } @@ -1855,10 +1912,10 @@ NodeSet<std::string> InterpreterImpl::getTargetStates(const Arabica::DOM::Node<s assert(boost::ends_with(TAGNAME(transition), "transition")); // if we are called with a state, process all its transitions - if (isState(transition) || (transition.getNodeType() == Node_base::ELEMENT_NODE && iequals(_xmlNSPrefix + "initial", TAGNAME(transition)))) { + if (isState(transition) || (transition.getNodeType() == Node_base::ELEMENT_NODE && iequals(_nsInfo.xmlNSPrefix + "initial", TAGNAME(transition)))) { NodeList<std::string> childs = transition.getChildNodes(); for (int i = 0; i < childs.getLength(); i++) { - if (childs.item(i).getNodeType() == Node_base::ELEMENT_NODE && iequals(TAGNAME(childs.item(i)), _xmlNSPrefix + "transition")) { + if (childs.item(i).getNodeType() == Node_base::ELEMENT_NODE && iequals(TAGNAME(childs.item(i)), _nsInfo.xmlNSPrefix + "transition")) { targetStates.push_back(getTargetStates(childs.item(i))); } } @@ -1884,7 +1941,7 @@ NodeSet<std::string> InterpreterImpl::getTargetStates(const Arabica::XPath::Node } return targets; } - + std::list<std::string> InterpreterImpl::tokenizeIdRefs(const std::string& idRefs) { std::list<std::string> ids; @@ -1940,28 +1997,61 @@ std::string InterpreterImpl::spaceNormalize(const std::string& text) { } -NodeSet<std::string> InterpreterImpl::filterChildElements(const std::string& tagName, const NodeSet<std::string>& nodeSet) { +NodeSet<std::string> InterpreterImpl::filterChildElements(const std::string& tagName, const NodeSet<std::string>& nodeSet, bool recurse) { NodeSet<std::string> filteredChildElems; for (unsigned int i = 0; i < nodeSet.size(); i++) { - filteredChildElems.push_back(filterChildElements(tagName, nodeSet[i])); + filteredChildElems.push_back(filterChildElements(tagName, nodeSet[i], recurse)); } return filteredChildElems; } -NodeSet<std::string> InterpreterImpl::filterChildElements(const std::string& tagName, const Node<std::string>& node) { +NodeSet<std::string> InterpreterImpl::filterChildElements(const std::string& tagName, const Node<std::string>& node, bool recurse) { NodeSet<std::string> filteredChildElems; + + if (!node) + return filteredChildElems; + NodeList<std::string> childs = node.getChildNodes(); for (unsigned int i = 0; i < childs.getLength(); i++) { - if (childs.item(i).getNodeType() != Node_base::ELEMENT_NODE) - continue; -// std::cout << tagName << " vs " << TAGNAME(childs.item(i)) << std::endl; - if (!iequals(TAGNAME(childs.item(i)), tagName)) - continue; - filteredChildElems.push_back(childs.item(i)); + if (childs.item(i).getNodeType() == Node_base::ELEMENT_NODE) { +// std::cout << TAGNAME(childs.item(i)) << std::endl; + if(iequals(TAGNAME(childs.item(i)), tagName)) { + filteredChildElems.push_back(childs.item(i)); + } + } + if (recurse) { + filteredChildElems.push_back(filterChildElements(tagName, childs.item(i), recurse)); + } } 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++) { + filteredChildType.push_back(filterChildType(type, nodeSet[i], recurse)); + } + return filteredChildType; +} + +NodeSet<std::string> InterpreterImpl::filterChildType(const Node_base::Type type, const Node<std::string>& node, bool recurse) { + NodeSet<std::string> filteredChildTypes; + + if (!node) + return filteredChildTypes; + + NodeList<std::string> childs = node.getChildNodes(); + for (unsigned int i = 0; i < childs.getLength(); i++) { + if (childs.item(i).getNodeType() == type) + filteredChildTypes.push_back(childs.item(i)); + if (recurse) { + filteredChildTypes.push_back(filterChildType(type, childs.item(i), recurse)); + } + } + return filteredChildTypes; +} + + NodeSet<std::string> InterpreterImpl::getProperAncestors(const Arabica::DOM::Node<std::string>& s1, const Arabica::DOM::Node<std::string>& s2) { NodeSet<std::string> ancestors; @@ -1970,9 +2060,11 @@ NodeSet<std::string> InterpreterImpl::getProperAncestors(const Arabica::DOM::Nod while((node = node.getParentNode())) { if (!isState(node)) break; - if (iequals(TAGNAME(node), _xmlNSPrefix + "scxml")) // do not return scxml root itself - this is somewhat ill-defined + if (iequals(TAGNAME(node), _nsInfo.xmlNSPrefix + "scxml")) // do not return scxml root itself - this is somewhat ill-defined break; - if (!iequals(TAGNAME(node), _xmlNSPrefix + "parallel") && !iequals(TAGNAME(node), _xmlNSPrefix + "state") && !iequals(TAGNAME(node), _xmlNSPrefix + "scxml")) + if (!iequals(TAGNAME(node), _nsInfo.xmlNSPrefix + "parallel") && + !iequals(TAGNAME(node), _nsInfo.xmlNSPrefix + "state") && + !iequals(TAGNAME(node), _nsInfo.xmlNSPrefix + "scxml")) break; if (node == s2) break; @@ -2319,10 +2411,10 @@ bool InterpreterImpl::isInState(const std::string& stateId) { } return false; } else { - + for (int i = 0; i < _configuration.size(); i++) { if (HAS_ATTR(_configuration[i], "id") && - iequals(ATTR(_configuration[i], "id"), stateId)) { + iequals(ATTR(_configuration[i], "id"), stateId)) { return true; } } @@ -2335,7 +2427,7 @@ void InterpreterImpl::DOMEventListener::handleEvent(Arabica::DOM::Events::Event< if (event.getType().compare("DOMAttrModified") == 0) // we do not care about attributes return; Node<std::string> target = Arabica::DOM::Node<std::string>(event.getTarget()); - NodeSet<std::string> childs = Interpreter::filterChildElements(_interpreter->_xmlNSPrefix + "state", target); + NodeSet<std::string> childs = Interpreter::filterChildElements(_interpreter->_nsInfo.xmlNSPrefix + "state", target); for (int i = 0; i < childs.size(); i++) { if (HAS_ATTR(childs[i], "id")) { _interpreter->_cachedStates.erase(ATTR(childs[i], "id")); diff --git a/src/uscxml/Interpreter.h b/src/uscxml/Interpreter.h index ca0b3a2..a18bc28 100644 --- a/src/uscxml/Interpreter.h +++ b/src/uscxml/Interpreter.h @@ -138,6 +138,51 @@ protected: {} }; +class NameSpaceInfo { +public: + NameSpaceInfo() { + init(std::map<std::string, std::string>()); + } + + NameSpaceInfo(const std::map<std::string, std::string>& nsInfo) { + init(nsInfo); + } + + NameSpaceInfo(const NameSpaceInfo& other) { + 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 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 + Arabica::XPath::StandardNamespaceContext<std::string>* nsContext; + std::map<std::string, std::string> nsToPrefix; // prefixes for a given namespace + std::map<std::string, std::string> nsInfo; // all xmlns mappings + +private: + void init(const std::map<std::string, std::string>& nsInfo); +}; + class USCXML_API InterpreterImpl : public boost::enable_shared_from_this<InterpreterImpl> { public: @@ -150,6 +195,9 @@ public: virtual ~InterpreterImpl(); + void copyTo(InterpreterImpl* other); + void copyTo(boost::shared_ptr<InterpreterImpl> other); + void start(); void stop(); static void run(void*); @@ -206,28 +254,23 @@ public: Factory* getFactory() { return _factory; } - std::string getXPathPrefix() { - return _xpathPrefix; - } - std::string getXMLPrefix() { - return _xmlNSPrefix; - } - Arabica::XPath::StandardNamespaceContext<std::string>& getNSContext() { - return _nsContext; + + Arabica::XPath::NodeSet<std::string> getNodeSetForXPath(const std::string& xpathExpr) { + return _xpath.evaluate(xpathExpr, _scxml).asNodeSet(); } - std::string getXMLPrefixForNS(const std::string& ns) { - if (_nameSpaceInfo.find(ns) != _nameSpaceInfo.end() && _nameSpaceInfo[ns].size()) - return _nameSpaceInfo[ns] + ":"; + + std::string getXMLPrefixForNS(const std::string& ns) const { + if (_nsInfo.nsToPrefix.find(ns) != _nsInfo.nsToPrefix.end() && _nsInfo.nsToPrefix.at(ns).size()) + return _nsInfo.nsToPrefix.at(ns) + ":"; return ""; } - - Arabica::XPath::NodeSet<std::string> getNodeSetForXPath(const std::string& xpathExpr) { - return _xpath.evaluate(xpathExpr, _scxml).asNodeSet(); + + void setNameSpaceInfo(const NameSpaceInfo& nsInfo) { + _nsInfo = nsInfo; + _xpath.setNamespaceContext(*_nsInfo.nsContext); } - - void setNameSpaceInfo(const std::map<std::string, std::string> nameSpaceInfo); - std::map<std::string, std::string> getNameSpaceInfo() { - return _nameSpaceInfo; + NameSpaceInfo getNameSpaceInfo() const { + return _nsInfo; } void receiveInternal(const Event& event); @@ -266,7 +309,7 @@ public: Arabica::XPath::NodeSet<std::string> getStates(const std::list<std::string>& stateIds); Arabica::XPath::NodeSet<std::string> getAllStates(); - virtual Arabica::DOM::Document<std::string>& getDocument() { + virtual Arabica::DOM::Document<std::string> getDocument() const { return _document; } @@ -329,8 +372,10 @@ public: virtual Arabica::XPath::NodeSet<std::string> getTargetStates(const Arabica::XPath::NodeSet<std::string>& transitions); virtual Arabica::DOM::Node<std::string> getSourceState(const Arabica::DOM::Node<std::string>& transition); - static Arabica::XPath::NodeSet<std::string> filterChildElements(const std::string& tagname, const Arabica::DOM::Node<std::string>& node); - static Arabica::XPath::NodeSet<std::string> filterChildElements(const std::string& tagName, const Arabica::XPath::NodeSet<std::string>& nodeSet); + static Arabica::XPath::NodeSet<std::string> filterChildElements(const std::string& tagname, const Arabica::DOM::Node<std::string>& node, bool recurse = false); + static Arabica::XPath::NodeSet<std::string> filterChildElements(const std::string& tagName, const Arabica::XPath::NodeSet<std::string>& nodeSet, bool recurse = false); + static Arabica::XPath::NodeSet<std::string> filterChildType(const Arabica::DOM::Node_base::Type type, const Arabica::DOM::Node<std::string>& node, bool recurse = false); + static Arabica::XPath::NodeSet<std::string> filterChildType(const Arabica::DOM::Node_base::Type type, const Arabica::XPath::NodeSet<std::string>& nodeSet, bool recurse = false); Arabica::DOM::Node<std::string> findLCCA(const Arabica::XPath::NodeSet<std::string>& states); virtual Arabica::XPath::NodeSet<std::string> getProperAncestors(const Arabica::DOM::Node<std::string>& s1, const Arabica::DOM::Node<std::string>& s2); @@ -360,12 +405,7 @@ protected: Arabica::DOM::Document<std::string> _document; Arabica::DOM::Element<std::string> _scxml; Arabica::XPath::XPath<std::string> _xpath; - Arabica::XPath::StandardNamespaceContext<std::string> _nsContext; - std::string _xmlNSPrefix; // the actual prefix for elements in the xml file - std::string _xpathPrefix; // prefix mapped for xpath, "scxml" is _xmlNSPrefix is empty but _nsURL set - std::string _nsURL; // ough to be "http://www.w3.org/2005/07/scxml" - std::map<std::string, std::string> _nsToPrefix; - std::map<std::string, std::string> _nameSpaceInfo; + NameSpaceInfo _nsInfo; bool _running; bool _done; @@ -445,10 +485,11 @@ protected: class USCXML_API Interpreter { public: static Interpreter fromDOM(const Arabica::DOM::Document<std::string>& dom, - const std::map<std::string, std::string>& nameSpaceInfo); + const NameSpaceInfo& nameSpaceInfo); static Interpreter fromXML(const std::string& xml); static Interpreter fromURI(const std::string& uri); static Interpreter fromInputSource(Arabica::SAX::InputSource<std::string>& source); + static Interpreter fromClone(const Interpreter& other); Interpreter() : _impl() {} // the empty, invalid interpreter Interpreter(boost::shared_ptr<InterpreterImpl> const impl) : _impl(impl) { } @@ -489,28 +530,32 @@ public: _impl->interpret(); }; - void addMonitor(InterpreterMonitor* monitor) { + void addMonitor(InterpreterMonitor* monitor) { return _impl->addMonitor(monitor); } - void removeMonitor(InterpreterMonitor* monitor) { + void removeMonitor(InterpreterMonitor* monitor) { return _impl->removeMonitor(monitor); } - void setSourceURI(std::string sourceURI) { + void setSourceURI(std::string sourceURI) { return _impl->setSourceURI(sourceURI); } - URL getSourceURI() { + URL getSourceURI() { return _impl->getSourceURI(); } - URL getBaseURI() { + URL getBaseURI() { return _impl->getBaseURI(); } - void setNameSpaceInfo(const std::map<std::string, std::string> namespaceInfo) { - _impl->setNameSpaceInfo(namespaceInfo); + std::string getXMLPrefixForNS(const std::string& ns) const { + return _impl->getXMLPrefixForNS(ns); + } + + void setNameSpaceInfo(const NameSpaceInfo& nsInfo) { + _impl->setNameSpaceInfo(nsInfo); } - std::map<std::string, std::string> getNameSpaceInfo() { + NameSpaceInfo getNameSpaceInfo() const { return _impl->getNameSpaceInfo(); } @@ -525,7 +570,7 @@ public: return _impl->getHTTPServlet(); } - DataModel getDataModel() { + DataModel getDataModel() { return _impl->getDataModel(); } void setParentQueue(uscxml::concurrency::BlockingQueue<SendRequest>* parentQueue) { @@ -537,26 +582,14 @@ public: Factory* getFactory() { return _impl->getFactory(); } - std::string getXPathPrefix() { - return _impl->getXPathPrefix(); - } - std::string getXMLPrefix() { - return _impl->getXMLPrefix(); - } - Arabica::XPath::StandardNamespaceContext<std::string>& getNSContext() { - return _impl->getNSContext(); - } - std::string getXMLPrefixForNS(const std::string& ns) { - return _impl->getXMLPrefixForNS(ns); - } Arabica::XPath::NodeSet<std::string> getNodeSetForXPath(const std::string& xpathExpr) { return _impl->getNodeSetForXPath(xpathExpr); } - + void inline receiveInternal(const Event& event) { return _impl->receiveInternal(event); } - void receive(const Event& event, bool toFront = false) { + void receive(const Event& event, bool toFront = false) { return _impl->receive(event, toFront); } @@ -567,12 +600,12 @@ public: bool isInState(const std::string& stateId) { return _impl->isInState(stateId); } - - Arabica::XPath::NodeSet<std::string> getConfiguration() { + + Arabica::XPath::NodeSet<std::string> getConfiguration() { return _impl->getConfiguration(); } - Arabica::XPath::NodeSet<std::string> getBasicConfiguration() { + Arabica::XPath::NodeSet<std::string> getBasicConfiguration() { return _impl->getBasicConfiguration(); } @@ -593,11 +626,11 @@ public: return _impl->getAllStates(); } - Arabica::DOM::Document<std::string>& getDocument() { + Arabica::DOM::Document<std::string> getDocument() const { return _impl->getDocument(); } - void setCapabilities(unsigned int capabilities) { + void setCapabilities(unsigned int capabilities) { return _impl->setCapabilities(capabilities); } @@ -605,13 +638,13 @@ public: return _impl->setName(name); } - const std::string& getName() { + const std::string& getName() { return _impl->getName(); } - const std::string& getSessionId() { + const std::string& getSessionId() { return _impl->getSessionId(); } - DelayedEventQueue* getDelayQueue() { + DelayedEventQueue* getDelayQueue() { return _impl->getDelayQueue(); } @@ -716,12 +749,19 @@ public: return _impl->getSourceState(transition); } - static Arabica::XPath::NodeSet<std::string> filterChildElements(const std::string& tagname, const Arabica::DOM::Node<std::string>& node) { - return InterpreterImpl::filterChildElements(tagname, node); + static Arabica::XPath::NodeSet<std::string> filterChildElements(const std::string& tagname, const Arabica::DOM::Node<std::string>& node, bool recurse = false) { + return InterpreterImpl::filterChildElements(tagname, node, recurse); } - static Arabica::XPath::NodeSet<std::string> filterChildElements(const std::string& tagName, const Arabica::XPath::NodeSet<std::string>& nodeSet) { - return InterpreterImpl::filterChildElements(tagName, nodeSet); + static Arabica::XPath::NodeSet<std::string> filterChildElements(const std::string& tagName, const Arabica::XPath::NodeSet<std::string>& nodeSet, bool recurse = false) { + return InterpreterImpl::filterChildElements(tagName, nodeSet, recurse); } + static Arabica::XPath::NodeSet<std::string> filterChildType(const Arabica::DOM::Node_base::Type type, const Arabica::DOM::Node<std::string>& node, bool recurse = false) { + return InterpreterImpl::filterChildType(type, node, recurse); + } + static Arabica::XPath::NodeSet<std::string> filterChildType(const Arabica::DOM::Node_base::Type type, const Arabica::XPath::NodeSet<std::string>& nodeSet, bool recurse = false) { + return InterpreterImpl::filterChildType(type, nodeSet, recurse); + } + Arabica::DOM::Node<std::string> findLCCA(const Arabica::XPath::NodeSet<std::string>& states) { return _impl->findLCCA(states); } @@ -729,7 +769,7 @@ public: return _impl->getProperAncestors(s1, s2); } - boost::shared_ptr<InterpreterImpl> getImpl() { + boost::shared_ptr<InterpreterImpl> getImpl() const { return _impl; } @@ -747,10 +787,10 @@ public: virtual void beforeProcessingEvent(Interpreter interpreter, const Event& event) {} virtual void beforeMicroStep(Interpreter interpreter) {} - + virtual void beforeExitingState(Interpreter interpreter, const Arabica::DOM::Element<std::string>& state, bool moreComing) {} virtual void afterExitingState(Interpreter interpreter, const Arabica::DOM::Element<std::string>& state, bool moreComing) {} - + virtual void beforeExecutingContent(Interpreter interpreter, const Arabica::DOM::Element<std::string>& element) {} virtual void afterExecutingContent(Interpreter interpreter, const Arabica::DOM::Element<std::string>& element) {} @@ -762,14 +802,14 @@ public: virtual void beforeEnteringState(Interpreter interpreter, const Arabica::DOM::Element<std::string>& state, bool moreComing) {} virtual void afterEnteringState(Interpreter interpreter, const Arabica::DOM::Element<std::string>& state, bool moreComing) {} - + virtual void beforeInvoking(Interpreter interpreter, const Arabica::DOM::Element<std::string>& invokeElem, const std::string& invokeid) {} virtual void afterInvoking(Interpreter interpreter, const Arabica::DOM::Element<std::string>& invokeElem, const std::string& invokeid) {} virtual void afterMicroStep(Interpreter interpreter) {} virtual void onStableConfiguration(Interpreter interpreter) {} - + virtual void beforeCompletion(Interpreter interpreter) {} virtual void afterCompletion(Interpreter interpreter) {} diff --git a/src/uscxml/Message.cpp b/src/uscxml/Message.cpp index 33dca84..55be0e4 100644 --- a/src/uscxml/Message.cpp +++ b/src/uscxml/Message.cpp @@ -225,7 +225,9 @@ Arabica::DOM::Document<std::string> Data::toDocument() { scxmlMsg.setAttribute("version", "1.0"); if (compound.size() > 0 || array.size() > 0) { - Arabica::DOM::Element<std::string> payloadElem = document.createElementNS("http://www.w3.org/2005/07/scxml", "scxml:payload"); + Arabica::DOM::Element<std::string> payloadElem = document.createElementNS("http://www.w3.org/2005/07/scxml", "payload"); + payloadElem.setPrefix("scxml"); + scxmlMsg.appendChild(payloadElem); // we do not support nested attibutes @@ -233,7 +235,9 @@ Arabica::DOM::Document<std::string> Data::toDocument() { std::map<std::string, Data>::iterator compoundIter = compound.begin(); while(compoundIter != compound.end()) { if (compoundIter->second.atom.size() > 0) { - Arabica::DOM::Element<std::string> propertyElem = document.createElementNS("http://www.w3.org/2005/07/scxml", "scxml:property"); + Arabica::DOM::Element<std::string> propertyElem = document.createElementNS("http://www.w3.org/2005/07/scxml", "property"); + propertyElem.setPrefix("scxml"); + propertyElem.setAttribute("name", compoundIter->first); Arabica::DOM::Text<std::string> textElem = document.createTextNode(compoundIter->second.atom); propertyElem.appendChild(textElem); @@ -299,7 +303,9 @@ Arabica::DOM::Document<std::string> SendRequest::toDocument() { if (params.size() > 0 || namelist.size() > 0) { Arabica::DOM::NodeList<std::string> payload = scxmlMsg.getElementsByTagName("scxml:payload"); if (payload.getLength() == 0) { - Arabica::DOM::Element<std::string> payloadElem = document.createElementNS("http://www.w3.org/2005/07/scxml", "scxml:payload"); + Arabica::DOM::Element<std::string> payloadElem = document.createElementNS("http://www.w3.org/2005/07/scxml", "payload"); + payloadElem.setPrefix("scxml"); + scxmlMsg.appendChild(payloadElem); } Arabica::DOM::Node<std::string> payloadElem = scxmlMsg.getElementsByTagName("scxml:payload").item(0); @@ -307,7 +313,9 @@ Arabica::DOM::Document<std::string> SendRequest::toDocument() { // add parameters std::multimap<std::string, Data>::iterator paramIter = params.begin(); while(paramIter != params.end()) { - Arabica::DOM::Element<std::string> propertyElem = document.createElementNS("http://www.w3.org/2005/07/scxml", "scxml:property"); + Arabica::DOM::Element<std::string> propertyElem = document.createElementNS("http://www.w3.org/2005/07/scxml", "property"); + propertyElem.setPrefix("scxml"); + propertyElem.setAttribute("name", paramIter->first); // this is simplified - Data might be more elaborate than a simple string atom Arabica::DOM::Text<std::string> textElem = document.createTextNode(paramIter->second.atom); @@ -319,7 +327,9 @@ Arabica::DOM::Document<std::string> SendRequest::toDocument() { // add namelist elements std::map<std::string, Data>::iterator namelistIter = namelist.begin(); while(namelistIter != namelist.end()) { - Arabica::DOM::Element<std::string> propertyElem = document.createElementNS("http://www.w3.org/2005/07/scxml", "scxml:property"); + Arabica::DOM::Element<std::string> propertyElem = document.createElementNS("http://www.w3.org/2005/07/scxml", "property"); + propertyElem.setPrefix("scxml"); + propertyElem.setAttribute("name", namelistIter->first); // this is simplified - Data might be more elaborate than a simple string atom Arabica::DOM::Text<std::string> textElem = document.createTextNode(namelistIter->second.atom); diff --git a/src/uscxml/Message.h b/src/uscxml/Message.h index afc30ad..57e8680 100644 --- a/src/uscxml/Message.h +++ b/src/uscxml/Message.h @@ -71,7 +71,7 @@ public: }; Data() : type(INTERPRETED) {} - + // TODO: default INTERPRETED is unfortunate Data(const std::string& atom_, Type type_ = INTERPRETED) : atom(atom_), type(type_) {} Data(const char* data, size_t size, const std::string& mimeType, bool adopt = false); @@ -99,9 +99,9 @@ public: // we will have to drop this constructor as it interferes with operator Data() and entails C++11 template <typename T> Data(T value, typename std::enable_if<! std::is_base_of<Data, T>::value>::type* = nullptr) - : atom(toStr(value)), type(INTERPRETED) {} + : atom(toStr(value)), type(INTERPRETED) {} #endif - + explicit Data(const Arabica::DOM::Node<std::string>& dom); virtual ~Data() {} @@ -119,7 +119,7 @@ public: Data& operator[](const std::string& key) { return operator[](key.c_str()); } - + Data& operator[](const char* key) { return compound[key]; } @@ -143,7 +143,7 @@ public: Data data; return data; } - + const Data item(const size_t index) const { if (array.size() < index) { std::list<Data>::const_iterator arrayIter; @@ -153,7 +153,7 @@ public: Data data; return data; } - + bool operator==(const Data &other) const { if (other.atom.size() != atom.size()) return false; diff --git a/src/uscxml/concurrency/BlockingQueue.h b/src/uscxml/concurrency/BlockingQueue.h index fc62fce..e53de25 100644 --- a/src/uscxml/concurrency/BlockingQueue.h +++ b/src/uscxml/concurrency/BlockingQueue.h @@ -61,7 +61,7 @@ public: tthread::lock_guard<tthread::mutex> lock(_mutex); _queue.clear(); } - + virtual bool isEmpty() { tthread::lock_guard<tthread::mutex> lock(_mutex); return _queue.empty(); diff --git a/src/uscxml/debug/Breakpoint.cpp b/src/uscxml/debug/Breakpoint.cpp index 0001127..54f5d75 100644 --- a/src/uscxml/debug/Breakpoint.cpp +++ b/src/uscxml/debug/Breakpoint.cpp @@ -24,7 +24,7 @@ namespace uscxml { Breakpoint::Breakpoint(const Data& data) { - enabled = true; + enabled = true; subject = UNDEF_SUBJECT; when = UNDEF_WHEN; action = UNDEF_ACTION; @@ -105,60 +105,60 @@ Data Breakpoint::toData() const { Data data; switch (subject) { - case STATE: - data.compound["subject"] = Data("state", Data::VERBATIM); - break; - case TRANSITION: - data.compound["subject"] = Data("transition", Data::VERBATIM); - break; - case STABLE: - data.compound["subject"] = Data("stable", Data::VERBATIM); - break; - case MICROSTEP: - data.compound["subject"] = Data("microstep", Data::VERBATIM); - break; - case EVENT: - data.compound["subject"] = Data("event", Data::VERBATIM); - break; - case INVOKER: - data.compound["subject"] = Data("invoker", Data::VERBATIM); - break; - case EXECUTABLE: - data.compound["subject"] = Data("executable", Data::VERBATIM); - break; - default: - break; + case STATE: + data.compound["subject"] = Data("state", Data::VERBATIM); + break; + case TRANSITION: + data.compound["subject"] = Data("transition", Data::VERBATIM); + break; + case STABLE: + data.compound["subject"] = Data("stable", Data::VERBATIM); + break; + case MICROSTEP: + data.compound["subject"] = Data("microstep", Data::VERBATIM); + break; + case EVENT: + data.compound["subject"] = Data("event", Data::VERBATIM); + break; + case INVOKER: + data.compound["subject"] = Data("invoker", Data::VERBATIM); + break; + case EXECUTABLE: + data.compound["subject"] = Data("executable", Data::VERBATIM); + break; + default: + break; } - + switch (when) { - case AFTER: - data.compound["when"] = Data("after", Data::VERBATIM); - break; - case BEFORE: - data.compound["when"] = Data("before", Data::VERBATIM); - break; - case ON: - data.compound["when"] = Data("on", Data::VERBATIM); - break; - default: - break; + case AFTER: + data.compound["when"] = Data("after", Data::VERBATIM); + break; + case BEFORE: + data.compound["when"] = Data("before", Data::VERBATIM); + break; + case ON: + data.compound["when"] = Data("on", Data::VERBATIM); + break; + default: + break; } switch (action) { - case ENTER: - data.compound["action"] = Data("enter", Data::VERBATIM); - break; - case EXIT: - data.compound["action"] = Data("exit", Data::VERBATIM); - break; - case INVOKE: - data.compound["action"] = Data("invoke", Data::VERBATIM); - break; - case UNINVOKE: - data.compound["action"] = Data("cancel", Data::VERBATIM); - break; - default: - break; + case ENTER: + data.compound["action"] = Data("enter", Data::VERBATIM); + break; + case EXIT: + data.compound["action"] = Data("exit", Data::VERBATIM); + break; + case INVOKE: + data.compound["action"] = Data("invoke", Data::VERBATIM); + break; + case UNINVOKE: + data.compound["action"] = Data("cancel", Data::VERBATIM); + break; + default: + break; } if (invokeId.length() > 0) @@ -176,7 +176,7 @@ Data Breakpoint::toData() const { if (executableXPath.length() > 0) { data.compound["executableXPath"] = Data(executableXPath, Data::VERBATIM); } - + if (element) data.compound["xpath"] = Data(DOMUtils::xPathForNode(element, "*"), Data::VERBATIM); @@ -194,20 +194,20 @@ Data Breakpoint::toData() const { return data; } - + bool Breakpoint::matches(Interpreter interpreter, const Breakpoint& other) const { // would we match the given breakpoint? if (subject != UNDEF_SUBJECT && - other.subject != subject) + other.subject != subject) return false; // subject does not match - + if (when != UNDEF_WHEN && - other.when != when) + other.when != when) return false; // time does not match - + if (action != UNDEF_ACTION && - other.action != action) + other.action != action) return false; // action does not match // when we have a qualifier it has to match @@ -248,7 +248,7 @@ bool Breakpoint::matches(Interpreter interpreter, const Breakpoint& other) const if(transTargetId.length() > 0 && transTargetId != other.transTargetId) { return false; } - + if (condition.length() > 0) { try { DataModel dm = interpreter.getDataModel(); diff --git a/src/uscxml/debug/Breakpoint.h b/src/uscxml/debug/Breakpoint.h index 157a56d..c48b841 100644 --- a/src/uscxml/debug/Breakpoint.h +++ b/src/uscxml/debug/Breakpoint.h @@ -27,61 +27,61 @@ namespace uscxml { class USCXML_API Breakpoint { public: - + enum When { - UNDEF_WHEN, AFTER, BEFORE, ON + UNDEF_WHEN, AFTER, BEFORE, ON }; - + enum Subject { - UNDEF_SUBJECT, STATE, TRANSITION, STABLE, MICROSTEP, EVENT, INVOKER, EXECUTABLE + UNDEF_SUBJECT, STATE, TRANSITION, STABLE, MICROSTEP, EVENT, INVOKER, EXECUTABLE }; - + enum Action { - UNDEF_ACTION, ENTER, EXIT, INVOKE, UNINVOKE + UNDEF_ACTION, ENTER, EXIT, INVOKE, UNINVOKE }; - + Breakpoint() { subject = UNDEF_SUBJECT; when = UNDEF_WHEN; action = UNDEF_ACTION; } Breakpoint(const Data& data); - + // would we match the given breakpoint as well? bool matches(Interpreter interpreter, const Breakpoint& other) const; - + Data toData() const; - + bool operator<(const Breakpoint& other) const { return (toData() < other.toData()); } - + operator bool() { return (subject != UNDEF_SUBJECT || - when != UNDEF_WHEN || - action != UNDEF_ACTION); + when != UNDEF_WHEN || + action != UNDEF_ACTION); } - + mutable bool enabled; - + When when; Subject subject; Action action; Arabica::DOM::Element<std::string> element; - + std::string invokeId; std::string invokeType; std::string eventName; - + std::string executableName; std::string executableXPath; - + std::string stateId; std::string transSourceId; std::string transTargetId; - + std::string condition; }; diff --git a/src/uscxml/debug/DebugSession.cpp b/src/uscxml/debug/DebugSession.cpp index e785c84..c73f53e 100644 --- a/src/uscxml/debug/DebugSession.cpp +++ b/src/uscxml/debug/DebugSession.cpp @@ -21,16 +21,16 @@ #include "uscxml/debug/Debugger.h" namespace uscxml { - + void DebugSession::checkBreakpoints(const std::list<Breakpoint> qualifiedBreakpoints) { std::list<Breakpoint>::const_iterator qualifiedBreakpointIter = qualifiedBreakpoints.begin(); if (!_breakpointsEnabled) return; - + while(qualifiedBreakpointIter != qualifiedBreakpoints.end()) { const Breakpoint& qualifiedBreakpoint = *qualifiedBreakpointIter++; - + // check if one of the user-supplied breakpoints match bool userBreakpointMatched = false; Data replyData; @@ -44,7 +44,7 @@ void DebugSession::checkBreakpoints(const std::list<Breakpoint> qualifiedBreakpo } continue; } - + std::set<Breakpoint>::const_iterator breakpointIter = _breakPoints.begin(); while(breakpointIter != _breakPoints.end()) { const Breakpoint& breakpoint = *breakpointIter++; @@ -52,10 +52,10 @@ void DebugSession::checkBreakpoints(const std::list<Breakpoint> qualifiedBreakpo continue; if (breakpoint.matches(_interpreter, qualifiedBreakpoint)) { // do we have a condition? - + replyData.compound["breakpoint"] = breakpoint.toData(); replyData.compound["qualified"] = qualifiedBreakpoint.toData(); - + userBreakpointMatched = true; breakExecution(replyData); } @@ -70,7 +70,7 @@ void DebugSession::checkBreakpoints(const std::list<Breakpoint> qualifiedBreakpo void DebugSession::breakExecution(Data replyData) { tthread::lock_guard<tthread::recursive_mutex> lock(_mutex); - + Arabica::XPath::NodeSet<std::string> basicConf = _interpreter.getBasicConfiguration(); for (int i = 0; i < basicConf.size(); i++) { Arabica::DOM::Element<std::string> element = Arabica::DOM::Element<std::string>(basicConf[i]); @@ -94,7 +94,7 @@ void DebugSession::breakExecution(Data replyData) { Data DebugSession::debugPrepare(const Data& data) { Data replyData; - + if (!data.hasKey("xml") && !data.hasKey("url")) { replyData.compound["status"] = Data("failure", Data::VERBATIM); replyData.compound["reason"] = Data("No XML or URL given", Data::VERBATIM); @@ -102,7 +102,7 @@ Data DebugSession::debugPrepare(const Data& data) { } debugStop(data); - + _isAttached = false; if (data.hasKey("xml")) { @@ -112,7 +112,7 @@ Data DebugSession::debugPrepare(const Data& data) { } else { _interpreter = Interpreter(); } - + if (_interpreter) { // register ourself as a monitor _interpreter.addMonitor(_debugger); @@ -132,22 +132,22 @@ Data DebugSession::debugPrepare(const Data& data) { Data DebugSession::debugAttach(const Data& data) { Data replyData; _isAttached = true; - + if (!data.hasKey("attach")) { replyData.compound["status"] = Data("failure", Data::VERBATIM); replyData.compound["reason"] = Data("No id to attach to given", Data::VERBATIM); return replyData; } - + std::string interpreterId = data.at("attach").atom; bool interpreterFound = false; - + // find interpreter for sessionid std::map<std::string, boost::weak_ptr<InterpreterImpl> > instances = Interpreter::getInstances(); for (std::map<std::string, boost::weak_ptr<InterpreterImpl> >::iterator instIter = instances.begin(); - instIter != instances.end(); - instIter++) { - + instIter != instances.end(); + instIter++) { + boost::shared_ptr<InterpreterImpl> instance = instIter->second.lock(); if (instance && instance->getSessionId() == interpreterId) { _interpreter = instance; @@ -156,7 +156,7 @@ Data DebugSession::debugAttach(const Data& data) { break; } } - + if (!interpreterFound) { replyData.compound["status"] = Data("failure", Data::VERBATIM); replyData.compound["reason"] = Data("No interpreter with given id found", Data::VERBATIM); @@ -179,7 +179,7 @@ Data DebugSession::debugDetach(const Data& data) { Data DebugSession::debugStart(const Data& data) { Data replyData; - + if (_isAttached) { replyData.compound["reason"] = Data("Already started when attached", Data::VERBATIM); replyData.compound["status"] = Data("failure", Data::VERBATIM); @@ -201,7 +201,7 @@ Data DebugSession::debugStop(const Data& data) { // detach from old intepreter _debugger->detachSession(_interpreter); } - + if (_interpreter && !_isAttached) _interpreter.stop(); // unblock @@ -212,16 +212,16 @@ Data DebugSession::debugStop(const Data& data) { // calls destructor _interpreter = Interpreter(); - + return replyData; } - + Data DebugSession::debugStep(const Data& data) { tthread::lock_guard<tthread::recursive_mutex> lock(_mutex); - + stepping(true); _resumeCond.notify_one(); - + Data replyData; if (_interpreter) { // register ourself as a monitor @@ -233,19 +233,19 @@ Data DebugSession::debugStep(const Data& data) { } return replyData; } - + Data DebugSession::debugResume(const Data& data) { tthread::lock_guard<tthread::recursive_mutex> lock(_mutex); - + stepping(false); - + Data replyData; replyData.compound["status"] = Data("success", Data::VERBATIM); - + _resumeCond.notify_one(); return replyData; } - + Data DebugSession::debugPause(const Data& data) { tthread::lock_guard<tthread::recursive_mutex> lock(_mutex); @@ -261,12 +261,12 @@ Data DebugSession::debugPause(const Data& data) { Data DebugSession::skipToBreakPoint(const Data& data) { tthread::lock_guard<tthread::recursive_mutex> lock(_mutex); - + _skipTo = Breakpoint(data); - + Data replyData; replyData.compound["status"] = Data("success", Data::VERBATIM); - + _resumeCond.notify_one(); return replyData; } @@ -278,7 +278,7 @@ Data DebugSession::addBreakPoint(const Data& data) { if (_breakPoints.find(breakpoint) == _breakPoints.end()) { _breakPoints.insert(breakpoint); replyData.compound["status"] = Data("success", Data::VERBATIM); - + } else { replyData.compound["reason"] = Data("Breakpoint already exists", Data::VERBATIM); replyData.compound["status"] = Data("failure", Data::VERBATIM); @@ -316,7 +316,7 @@ Data DebugSession::enableBreakPoint(const Data& data) { } Data DebugSession::disableBreakPoint(const Data& data) { Breakpoint breakpoint(data); - + Data replyData; if (_breakPoints.find(breakpoint) != _breakPoints.end()) { _breakPoints.find(breakpoint)->enabled = false; @@ -325,7 +325,7 @@ Data DebugSession::disableBreakPoint(const Data& data) { replyData.compound["reason"] = Data("No such breakpoint", Data::VERBATIM); replyData.compound["status"] = Data("failure", Data::VERBATIM); } - + return replyData; } Data DebugSession::enableAllBreakPoints() { @@ -338,16 +338,16 @@ Data DebugSession::enableAllBreakPoints() { } Data DebugSession::disableAllBreakPoints() { Data replyData; - + _breakpointsEnabled = false; replyData.compound["status"] = Data("success", Data::VERBATIM); - + return replyData; } Data DebugSession::debugEval(const Data& data) { Data replyData; - + if (!data.hasKey("expression")) { replyData.compound["status"] = Data("failure", Data::VERBATIM); replyData.compound["reason"] = Data("No expression given", Data::VERBATIM); @@ -355,7 +355,7 @@ Data DebugSession::debugEval(const Data& data) { } std::string expr = data.at("expression").atom; - + if (!_interpreter) { replyData.compound["status"] = Data("failure", Data::VERBATIM); replyData.compound["reason"] = Data("No interpreter running", Data::VERBATIM); @@ -374,5 +374,5 @@ Data DebugSession::debugEval(const Data& data) { return replyData; } - + }
\ No newline at end of file diff --git a/src/uscxml/debug/DebugSession.h b/src/uscxml/debug/DebugSession.h index 12f1d93..1fb4f4d 100644 --- a/src/uscxml/debug/DebugSession.h +++ b/src/uscxml/debug/DebugSession.h @@ -27,7 +27,7 @@ namespace uscxml { class Debugger; - + class USCXML_API DebugSession : public boost::enable_shared_from_this<DebugSession> { public: DebugSession() { @@ -37,13 +37,13 @@ public: _markedForDeletion = false; _debugger = NULL; } - + void stepping(bool enable) { _isStepping = enable; } - + void checkBreakpoints(const std::list<Breakpoint> qualifiedBreakpoints); - + Data debugPrepare(const Data& data); Data debugAttach(const Data& data); Data debugDetach(const Data& data); @@ -60,26 +60,26 @@ public: Data enableAllBreakPoints(); Data disableAllBreakPoints(); Data debugEval(const Data& data); - + void setDebugger(Debugger* debugger) { _debugger = debugger; } - + Interpreter getInterpreter() { return _interpreter; } - + void markForDeletion(bool mark) { _markedForDeletion = mark; } - + protected: void breakExecution(Data replyData); bool _isStepping; bool _isAttached; bool _breakpointsEnabled; - + tthread::condition_variable _resumeCond; tthread::recursive_mutex _runMutex; tthread::recursive_mutex _mutex; @@ -89,7 +89,7 @@ protected: Interpreter _interpreter; std::set<Breakpoint> _breakPoints; Breakpoint _skipTo; - + }; diff --git a/src/uscxml/debug/Debugger.cpp b/src/uscxml/debug/Debugger.cpp index f611d09..d1a8068 100644 --- a/src/uscxml/debug/Debugger.cpp +++ b/src/uscxml/debug/Debugger.cpp @@ -21,7 +21,7 @@ #include "uscxml/DOMUtils.h" namespace uscxml { - + void Debugger::afterCompletion(Interpreter interpreter) { boost::shared_ptr<DebugSession> session = getSession(interpreter); if (!session) @@ -34,44 +34,44 @@ void Debugger::afterCompletion(Interpreter interpreter) { std::list<Breakpoint> getQualifiedStateBreakpoints(Interpreter interpreter, const Arabica::DOM::Element<std::string>& state, Breakpoint breakpointTemplate) { std::list<Breakpoint> breakpoints; - + Breakpoint bp = breakpointTemplate; // copy base as template bp.stateId = ATTR(state, "id"); bp.element = state; bp.subject = Breakpoint::STATE; breakpoints.push_back(bp); - + return breakpoints; } std::list<Breakpoint> getQualifiedInvokeBreakpoints(Interpreter interpreter, const Arabica::DOM::Element<std::string>& invokeElem, const std::string invokeId, Breakpoint breakpointTemplate) { std::list<Breakpoint> breakpoints; - + Breakpoint bp = breakpointTemplate; // copy base as template bp.subject = Breakpoint::INVOKER; bp.element = invokeElem; bp.invokeId = invokeId; - + if (HAS_ATTR(invokeElem, "type")) { bp.invokeType = ATTR(invokeElem, "type"); } else if (HAS_ATTR(invokeElem, "typeexpr")) { bp.invokeType = interpreter.getDataModel().evalAsString(ATTR(invokeElem, "typeexpr")); } - + breakpoints.push_back(bp); - + return breakpoints; } std::list<Breakpoint> getQualifiedTransBreakpoints(Interpreter interpreter, const Arabica::DOM::Element<std::string>& transition, Breakpoint breakpointTemplate) { std::list<Breakpoint> breakpoints; - + Arabica::DOM::Element<std::string> source(interpreter.getSourceState(transition)); Arabica::XPath::NodeSet<std::string> targets = interpreter.getTargetStates(transition); for (int j = 0; j < targets.size(); j++) { Arabica::DOM::Element<std::string> target(targets[j]); - + Breakpoint bp = breakpointTemplate; // copy base as template bp.element = transition; bp.transSourceId = ATTR(source, "id"); @@ -134,14 +134,14 @@ void Debugger::beforeProcessingEvent(Interpreter interpreter, const Event& event } void Debugger::handleExecutable(Interpreter interpreter, - const Arabica::DOM::Element<std::string>& execContentElem, - Breakpoint::When when) { + const Arabica::DOM::Element<std::string>& execContentElem, + Breakpoint::When when) { if (!interpreter.isRunning()) return; boost::shared_ptr<DebugSession> session = getSession(interpreter); if (!session) return; - + std::list<Breakpoint> breakpoints; Breakpoint breakpoint; @@ -150,7 +150,7 @@ void Debugger::handleExecutable(Interpreter interpreter, breakpoint.executableName = execContentElem.getLocalName(); breakpoint.subject = Breakpoint::EXECUTABLE; breakpoints.push_back(breakpoint); - + session->checkBreakpoints(breakpoints); } @@ -161,19 +161,19 @@ void Debugger::handleEvent(Interpreter interpreter, const Event& event, Breakpoi boost::shared_ptr<DebugSession> session = getSession(interpreter); if (!session) return; - + std::list<Breakpoint> breakpoints; - + Breakpoint breakpoint; breakpoint.when = when; breakpoint.eventName = event.name; breakpoint.subject = Breakpoint::EVENT; breakpoints.push_back(breakpoint); - + session->checkBreakpoints(breakpoints); } - + void Debugger::handleStable(Interpreter interpreter, Breakpoint::When when) { if (!interpreter.isRunning()) return; @@ -187,7 +187,7 @@ void Debugger::handleStable(Interpreter interpreter, Breakpoint::When when) { breakpoint.when = when; breakpoint.subject = Breakpoint::STABLE; breakpoints.push_back(breakpoint); - + session->checkBreakpoints(breakpoints); } @@ -199,12 +199,12 @@ void Debugger::handleMicrostep(Interpreter interpreter, Breakpoint::When when) { return; std::list<Breakpoint> breakpoints; - + Breakpoint breakpoint; breakpoint.when = when; breakpoint.subject = Breakpoint::MICROSTEP; breakpoints.push_back(breakpoint); - + session->checkBreakpoints(breakpoints); } diff --git a/src/uscxml/debug/Debugger.h b/src/uscxml/debug/Debugger.h index 8f840b0..9adbae6 100644 --- a/src/uscxml/debug/Debugger.h +++ b/src/uscxml/debug/Debugger.h @@ -24,15 +24,15 @@ #include "uscxml/Interpreter.h" #include "uscxml/debug/Breakpoint.h" #include "uscxml/debug/DebugSession.h" - + namespace uscxml { - + class USCXML_API Debugger : public InterpreterMonitor { public: Debugger() { } virtual ~Debugger() {} - + virtual void attachSession(Interpreter interpreter, boost::shared_ptr<DebugSession> session) { tthread::lock_guard<tthread::recursive_mutex> lock(_sessionMutex); _sessionForInterpreter[interpreter] = session; @@ -42,16 +42,16 @@ public: tthread::lock_guard<tthread::recursive_mutex> lock(_sessionMutex); _sessionForInterpreter.erase(interpreter); } - + virtual boost::shared_ptr<DebugSession> getSession(Interpreter interpreter) { tthread::lock_guard<tthread::recursive_mutex> lock(_sessionMutex); if (_sessionForInterpreter.find(interpreter) != _sessionForInterpreter.end()) return _sessionForInterpreter[interpreter]; return boost::shared_ptr<DebugSession>(); } - + virtual void pushData(boost::shared_ptr<DebugSession> session, Data pushData) = 0; - + // InterpreterMonitor virtual void beforeProcessingEvent(Interpreter interpreter, const Event& event); virtual void beforeMicroStep(Interpreter interpreter); @@ -73,28 +73,28 @@ public: virtual void afterCompletion(Interpreter interpreter); protected: - + void handleTransition(Interpreter interpreter, - const Arabica::DOM::Element<std::string>& transition, - Breakpoint::When when); + const Arabica::DOM::Element<std::string>& transition, + Breakpoint::When when); void handleState(Interpreter interpreter, - const Arabica::DOM::Element<std::string>& state, - Breakpoint::When when, - Breakpoint::Action action); + const Arabica::DOM::Element<std::string>& state, + Breakpoint::When when, + Breakpoint::Action action); void handleInvoke(Interpreter interpreter, - const Arabica::DOM::Element<std::string>& invokeElem, - const std::string& invokeId, - Breakpoint::When when, - Breakpoint::Action action); + const Arabica::DOM::Element<std::string>& invokeElem, + const std::string& invokeId, + Breakpoint::When when, + Breakpoint::Action action); void handleExecutable(Interpreter interpreter, - const Arabica::DOM::Element<std::string>& execContentElem, - Breakpoint::When when); + const Arabica::DOM::Element<std::string>& execContentElem, + Breakpoint::When when); void handleStable(Interpreter interpreter, Breakpoint::When when); void handleMicrostep(Interpreter interpreter, Breakpoint::When when); void handleEvent(Interpreter interpreter, const Event& event, Breakpoint::When when); tthread::recursive_mutex _sessionMutex; - std::map<Interpreter, boost::shared_ptr<DebugSession> > _sessionForInterpreter; + std::map<Interpreter, boost::shared_ptr<DebugSession> > _sessionForInterpreter; }; } diff --git a/src/uscxml/debug/DebuggerServlet.cpp b/src/uscxml/debug/DebuggerServlet.cpp index a570263..a99aaf8 100644 --- a/src/uscxml/debug/DebuggerServlet.cpp +++ b/src/uscxml/debug/DebuggerServlet.cpp @@ -25,24 +25,24 @@ namespace uscxml { void DebuggerServlet::pushData(boost::shared_ptr<DebugSession> session, Data pushData) { std::cout << "trying to push " << pushData["replyType"].atom << std::endl; - + if (!session) { if (_sendQueues.size() > 0) // logging is not aware of its interpreter _sendQueues.begin()->second.push(pushData); } else { _sendQueues[session].push(pushData); } - + serverPushData(session); } void DebuggerServlet::serverPushData(boost::shared_ptr<DebugSession> session) { if (_sendQueues[session].isEmpty()) return; - + if (!_clientConns[session]) return; - + Data reply = _sendQueues[session].pop(); std::cout << "pushing " << reply["replyType"].atom << std::endl; returnData(_clientConns[session], reply); @@ -51,13 +51,13 @@ void DebuggerServlet::serverPushData(boost::shared_ptr<DebugSession> session) { void DebuggerServlet::returnData(const HTTPServer::Request& request, Data replyData) { HTTPServer::Reply reply(request); - + if (!replyData.hasKey("status")) { replyData.compound["status"] = Data("success", Data::VERBATIM); } - + std::cout << "<- " << replyData << std::endl; - + reply.content = Data::toJSON(replyData); reply.headers["Access-Control-Allow-Origin"] = "*"; reply.headers["Content-Type"] = "application/json"; @@ -66,8 +66,8 @@ void DebuggerServlet::returnData(const HTTPServer::Request& request, Data replyD bool DebuggerServlet::isCORS(const HTTPServer::Request& request) { return (request.data.at("type").atom == "options" && - request.data.at("header").hasKey("Origin") && - request.data.at("header").hasKey("Access-Control-Request-Method")); + request.data.at("header").hasKey("Origin") && + request.data.at("header").hasKey("Access-Control-Request-Method")); } void DebuggerServlet::handleCORS(const HTTPServer::Request& request) { @@ -81,7 +81,7 @@ void DebuggerServlet::handleCORS(const HTTPServer::Request& request) { corsReply.headers["Access-Control-Allow-Methods"] = request.data.at("header").at("Access-Control-Request-Method").atom; if (request.data.at("header").hasKey("Access-Control-Request-Headers")) corsReply.headers["Access-Control-Allow-Headers"] = request.data.at("header").at("Access-Control-Request-Headers").atom; - + // std::cout << "CORS!" << std::endl << request << std::endl; HTTPServer::reply(corsReply); } @@ -89,14 +89,14 @@ void DebuggerServlet::handleCORS(const HTTPServer::Request& request) { bool DebuggerServlet::httpRecvRequest(const HTTPServer::Request& request) { if (!request.data.hasKey("path")) return false; // returnError(request); - + if (isCORS(request)) { handleCORS(request); return true; } - + std::cout << request.data["path"] << ": " << request.data["content"] << std::endl; - + Data replyData; // process request that don't need a session if (false) { @@ -107,7 +107,7 @@ bool DebuggerServlet::httpRecvRequest(const HTTPServer::Request& request) { processListSessions(request); return true; } - + // get session or return error if (false) { } else if (!request.data.at("content").hasKey("session")) { @@ -121,9 +121,9 @@ bool DebuggerServlet::httpRecvRequest(const HTTPServer::Request& request) { returnData(request, replyData); return true; } - + boost::shared_ptr<DebugSession> session = _sessionForId[request.data.at("content").at("session").atom]; - + if (false) { } else if (boost::starts_with(request.data.at("path").atom, "/debug/poll")) { // save long-standing client poll @@ -164,7 +164,7 @@ bool DebuggerServlet::httpRecvRequest(const HTTPServer::Request& request) { } else if (boost::starts_with(request.data.at("path").atom, "/debug/eval")) { replyData = session->debugEval(request.data["content"]); } - + if (replyData) { returnData(request, replyData); return true; @@ -177,10 +177,10 @@ bool DebuggerServlet::httpRecvRequest(const HTTPServer::Request& request) { void DebuggerServlet::processConnect(const HTTPServer::Request& request) { tthread::lock_guard<tthread::recursive_mutex> lock(_mutex); std::string sessionId = UUID::getUUID(); - + _sessionForId[sessionId] = boost::shared_ptr<DebugSession>(new DebugSession()); _sessionForId[sessionId]->setDebugger(this); - + Data replyData; replyData.compound["session"] = Data(sessionId, Data::VERBATIM); replyData.compound["status"] = Data("success", Data::VERBATIM); @@ -211,18 +211,18 @@ void DebuggerServlet::processDisconnect(const HTTPServer::Request& request) { _sendQueues.erase(_sessionForId[sessionId]); _sessionForId.erase(sessionId); } - + returnData(request, replyData); } void DebuggerServlet::processListSessions(const HTTPServer::Request& request) { Data replyData; - + std::map<std::string, boost::weak_ptr<InterpreterImpl> > instances = Interpreter::getInstances(); for (std::map<std::string, boost::weak_ptr<InterpreterImpl> >::iterator instIter = instances.begin(); - instIter != instances.end(); - instIter++) { - + instIter != instances.end(); + instIter++) { + boost::shared_ptr<InterpreterImpl> instance = instIter->second.lock(); if (instance) { Data sessionData; @@ -234,25 +234,25 @@ void DebuggerServlet::processListSessions(const HTTPServer::Request& request) { replyData.compound["sessions"].array.push_back(sessionData); } } - + replyData.compound["status"] = Data("success", Data::VERBATIM); returnData(request, replyData); } void DebuggerServlet::send(google::LogSeverity severity, const char* full_filename, - const char* base_filename, int line, - const struct ::tm* tm_time, - const char* message, size_t message_len) { - + const char* base_filename, int line, + const struct ::tm* tm_time, + const char* message, size_t message_len) { + // _sendQueue is thread-safe, not sure about ToString though LogMessage msg(severity, - full_filename, - base_filename, - line, - tm_time, - std::string(message, message_len), - ToString(severity, base_filename, line, tm_time, message, message_len)); + full_filename, + base_filename, + line, + tm_time, + std::string(message, message_len), + ToString(severity, base_filename, line, tm_time, message, message_len)); msg.compound["replyType"] = Data("log", Data::VERBATIM); pushData(boost::shared_ptr<DebugSession>(), msg); } diff --git a/src/uscxml/debug/DebuggerServlet.h b/src/uscxml/debug/DebuggerServlet.h index ae5178f..ce6f082 100644 --- a/src/uscxml/debug/DebuggerServlet.h +++ b/src/uscxml/debug/DebuggerServlet.h @@ -37,10 +37,10 @@ public: class LogMessage : public Data { public: LogMessage(google::LogSeverity severity, const char* full_filename, - const char* base_filename, int line, - const struct ::tm* tm_time, - std::string message, std::string formatted) { - + const char* base_filename, int line, + const struct ::tm* tm_time, + std::string message, std::string formatted) { + compound["severity"] = severity; compound["fullFilename"] = Data(full_filename, Data::VERBATIM); compound["baseFilename"] = Data(base_filename, Data::VERBATIM); @@ -50,9 +50,9 @@ public: compound["formatted"] = Data(formatted, Data::VERBATIM); } }; - + virtual ~DebuggerServlet() {} - + // from Debugger virtual void addBreakpoint(const Breakpoint& breakpoint) {}; @@ -85,20 +85,20 @@ public: // void processAddBreakPoint(const HTTPServer::Request& request); // void processRemoveBreakPoint(const HTTPServer::Request& request); // void processPoll(const HTTPServer::Request& request); - + // Logsink virtual void send(google::LogSeverity severity, const char* full_filename, - const char* base_filename, int line, - const struct ::tm* tm_time, - const char* message, size_t message_len); + const char* base_filename, int line, + const struct ::tm* tm_time, + const char* message, size_t message_len); protected: void serverPushData(boost::shared_ptr<DebugSession>); std::string _url; std::map<boost::shared_ptr<DebugSession>, HTTPServer::Request> _clientConns; - std::map<boost::shared_ptr<DebugSession>, concurrency::BlockingQueue<Data> > _sendQueues; - std::map<std::string, boost::shared_ptr<DebugSession> > _sessionForId; + std::map<boost::shared_ptr<DebugSession>, concurrency::BlockingQueue<Data> > _sendQueues; + std::map<std::string, boost::shared_ptr<DebugSession> > _sessionForId; tthread::recursive_mutex _mutex; }; diff --git a/src/uscxml/interpreter/InterpreterDraft6.cpp b/src/uscxml/interpreter/InterpreterDraft6.cpp index d286856..02dcff5 100644 --- a/src/uscxml/interpreter/InterpreterDraft6.cpp +++ b/src/uscxml/interpreter/InterpreterDraft6.cpp @@ -38,7 +38,7 @@ void InterpreterDraft6::interpret() { if (!_scxml) { return; } - // dump(); + // dump(); // just make sure we have a session id assert(_sessionId.length() > 0); @@ -75,17 +75,17 @@ void InterpreterDraft6::interpret() { if (_dataModel && _binding == EARLY) { // initialize all data elements - NodeSet<std::string> dataElems = _xpath.evaluate("//" + _xpathPrefix + "data", _scxml).asNodeSet(); + NodeSet<std::string> dataElems = _xpath.evaluate("//" + _nsInfo.xpathPrefix + "data", _scxml).asNodeSet(); for (unsigned int i = 0; i < dataElems.size(); i++) { // do not process data elements of nested documents from invokers - if (!getAncestorElement(dataElems[i], _xmlNSPrefix + "invoke")) + if (!getAncestorElement(dataElems[i], _nsInfo.xmlNSPrefix + "invoke")) if (dataElems[i].getNodeType() == Node_base::ELEMENT_NODE) { initializeData(Element<std::string>(dataElems[i])); } } } else if(_dataModel) { // initialize current data elements - NodeSet<std::string> topDataElems = filterChildElements(_xmlNSPrefix + "data", filterChildElements(_xmlNSPrefix + "datamodel", _scxml)); + NodeSet<std::string> topDataElems = filterChildElements(_nsInfo.xmlNSPrefix + "data", filterChildElements(_nsInfo.xmlNSPrefix + "datamodel", _scxml)); for (unsigned int i = 0; i < topDataElems.size(); i++) { if (topDataElems[i].getNodeType() == Node_base::ELEMENT_NODE) initializeData(Element<std::string>(topDataElems[i])); @@ -93,7 +93,7 @@ void InterpreterDraft6::interpret() { } // executeGlobalScriptElements - NodeSet<std::string> globalScriptElems = filterChildElements(_xmlNSPrefix + "script", _scxml); + NodeSet<std::string> globalScriptElems = filterChildElements(_nsInfo.xmlNSPrefix + "script", _scxml); for (unsigned int i = 0; i < globalScriptElems.size(); i++) { if (_dataModel) { executeContent(globalScriptElems[i]); @@ -104,7 +104,9 @@ void InterpreterDraft6::interpret() { if (_userDefinedStartConfiguration.size() > 0) { // we emulate entering a given configuration by creating a pseudo deep history - Element<std::string> initHistory = _document.createElementNS(_nsURL, "history"); + Element<std::string> initHistory = _document.createElementNS(_nsInfo.nsURL, "history"); + _nsInfo.setPrefix(initHistory); + initHistory.setAttribute("id", UUID::getUUID()); initHistory.setAttribute("type", "deep"); _scxml.insertBefore(initHistory, _scxml.getFirstChild()); @@ -116,9 +118,13 @@ void InterpreterDraft6::interpret() { } _historyValue[histId] = histStates; - Element<std::string> initialElem = _document.createElementNS(_nsURL, "initial"); + Element<std::string> initialElem = _document.createElementNS(_nsInfo.nsURL, "initial"); + _nsInfo.setPrefix(initialElem); + initialElem.setAttribute("generated", "true"); - Element<std::string> transitionElem = _document.createElementNS(_nsURL, "transition"); + Element<std::string> transitionElem = _document.createElementNS(_nsInfo.nsURL, "transition"); + _nsInfo.setPrefix(transitionElem); + transitionElem.setAttribute("target", histId); initialElem.appendChild(transitionElem); _scxml.appendChild(initialElem); @@ -126,16 +132,20 @@ void InterpreterDraft6::interpret() { } else { // try to get initial transition from initial element - initialTransitions = _xpath.evaluate("/" + _xpathPrefix + "initial/" + _xpathPrefix + "transition", _scxml).asNodeSet(); + initialTransitions = _xpath.evaluate("/" + _nsInfo.xpathPrefix + "initial/" + _nsInfo.xpathPrefix + "transition", _scxml).asNodeSet(); if (initialTransitions.size() == 0) { Arabica::XPath::NodeSet<std::string> initialStates; // fetch per draft initialStates = getInitialStates(); assert(initialStates.size() > 0); for (int i = 0; i < initialStates.size(); i++) { - Element<std::string> initialElem = _document.createElementNS(_nsURL, "initial"); + Element<std::string> initialElem = _document.createElementNS(_nsInfo.nsURL, "initial"); + _nsInfo.setPrefix(initialElem); + initialElem.setAttribute("generated", "true"); - Element<std::string> transitionElem = _document.createElementNS(_nsURL, "transition"); + Element<std::string> transitionElem = _document.createElementNS(_nsInfo.nsURL, "transition"); + _nsInfo.setPrefix(transitionElem); + transitionElem.setAttribute("target", ATTR(initialStates[i], "id")); initialElem.appendChild(transitionElem); _scxml.appendChild(initialElem); @@ -147,9 +157,9 @@ void InterpreterDraft6::interpret() { assert(initialTransitions.size() > 0); enterStates(initialTransitions); - // _mutex.unlock(); + // _mutex.unlock(); - // assert(hasLegalConfiguration()); + // assert(hasLegalConfiguration()); mainEventLoop(); } catch (boost::bad_weak_ptr e) { LOG(ERROR) << "Unclean shutdown " << std::endl << std::endl; @@ -178,7 +188,7 @@ void InterpreterDraft6::mainEventLoop() { } std::cout << std::endl; #endif - + enabledTransitions = selectEventlessTransitions(); if (enabledTransitions.size() == 0) { if (_internalQueue.size() == 0) { @@ -189,12 +199,13 @@ void InterpreterDraft6::mainEventLoop() { #if VERBOSE std::cout << "Received internal event " << _currEvent.name << std::endl; #endif - + // --- MONITOR: beforeProcessingEvent ------------------------------ for(monIter_t monIter = _monitors.begin(); monIter != _monitors.end(); monIter++) { try { (*monIter)->beforeProcessingEvent(shared_from_this(), _currEvent); - } USCXML_MONITOR_CATCH_BLOCK(beforeProcessingEvent) + } + USCXML_MONITOR_CATCH_BLOCK(beforeProcessingEvent) } if (_dataModel) @@ -210,7 +221,7 @@ void InterpreterDraft6::mainEventLoop() { } for (unsigned int i = 0; i < _statesToInvoke.size(); i++) { - NodeSet<std::string> invokes = filterChildElements(_xmlNSPrefix + "invoke", _statesToInvoke[i]); + NodeSet<std::string> invokes = filterChildElements(_nsInfo.xmlNSPrefix + "invoke", _statesToInvoke[i]); for (unsigned int j = 0; j < invokes.size(); j++) { if (!HAS_ATTR(invokes[j], "persist") || !DOMUtils::attributeIsTrue(ATTR(invokes[j], "persist"))) { invoke(invokes[j]); @@ -240,9 +251,10 @@ void InterpreterDraft6::mainEventLoop() { for(monIter_t monIter = _monitors.begin(); monIter != _monitors.end(); monIter++) { try { (*monIter)->onStableConfiguration(shared_from_this()); - } USCXML_MONITOR_CATCH_BLOCK(onStableConfiguration) + } + USCXML_MONITOR_CATCH_BLOCK(onStableConfiguration) } - + // } _mutex.unlock(); @@ -267,7 +279,8 @@ void InterpreterDraft6::mainEventLoop() { for(monIter_t monIter = _monitors.begin(); monIter != _monitors.end(); monIter++) { try { (*monIter)->beforeProcessingEvent(shared_from_this(), _currEvent); - } USCXML_MONITOR_CATCH_BLOCK(beforeProcessingEvent) + } + USCXML_MONITOR_CATCH_BLOCK(beforeProcessingEvent) } if (_dataModel && iequals(_currEvent.name, "cancel.invoke." + _sessionId)) @@ -321,10 +334,10 @@ void InterpreterDraft6::mainEventLoop() { } #else for (std::map<std::string, Invoker>::iterator invokeIter = _invokers.begin(); - invokeIter != _invokers.end(); - invokeIter++) { + invokeIter != _invokers.end(); + invokeIter++) { if (iequals(invokeIter->first, _currEvent.invokeid)) { - Arabica::XPath::NodeSet<std::string> finalizes = filterChildElements(_xmlNSPrefix + "finalize", invokeIter->second.getElement()); + Arabica::XPath::NodeSet<std::string> finalizes = filterChildElements(_nsInfo.xmlNSPrefix + "finalize", invokeIter->second.getElement()); for (int k = 0; k < finalizes.size(); k++) { Element<std::string> finalizeElem = Element<std::string>(finalizes[k]); executeContent(finalizeElem); @@ -355,7 +368,8 @@ EXIT_INTERPRETER: for(monIter_t monIter = _monitors.begin(); monIter != _monitors.end(); monIter++) { try { (*monIter)->beforeCompletion(shared_from_this()); - } USCXML_MONITOR_CATCH_BLOCK(beforeCompletion) + } + USCXML_MONITOR_CATCH_BLOCK(beforeCompletion) } exitInterpreter(); @@ -371,7 +385,8 @@ EXIT_INTERPRETER: for(monIter_t monIter = _monitors.begin(); monIter != _monitors.end(); monIter++) { try { (*monIter)->afterCompletion(shared_from_this()); - } USCXML_MONITOR_CATCH_BLOCK(afterCompletion) + } + USCXML_MONITOR_CATCH_BLOCK(afterCompletion) } } @@ -397,7 +412,7 @@ Arabica::XPath::NodeSet<std::string> InterpreterDraft6::selectTransitions(const unsigned int index = 0; while(states.size() > index) { bool foundTransition = false; - NodeSet<std::string> transitions = filterChildElements(_xmlNSPrefix + "transition", states[index]); + NodeSet<std::string> transitions = filterChildElements(_nsInfo.xmlNSPrefix + "transition", states[index]); for (unsigned int k = 0; k < transitions.size(); k++) { if (isEnabledTransition(transitions[k], event)) { enabledTransitions.push_back(transitions[k]); @@ -475,7 +490,7 @@ Arabica::XPath::NodeSet<std::string> InterpreterDraft6::selectEventlessTransitio unsigned int index = 0; while(states.size() > index) { bool foundTransition = false; - NodeSet<std::string> transitions = filterChildElements(_xmlNSPrefix + "transition", states[index]); + NodeSet<std::string> transitions = filterChildElements(_nsInfo.xmlNSPrefix + "transition", states[index]); for (unsigned int k = 0; k < transitions.size(); k++) { if (!HAS_ATTR(transitions[k], "event") && hasConditionMatch(transitions[k])) { enabledTransitions.push_back(transitions[k]); @@ -535,7 +550,7 @@ LOOP: } - + /** * Is t1 preempting t2? */ @@ -617,11 +632,12 @@ void InterpreterDraft6::microstep(const Arabica::XPath::NodeSet<std::string>& en for(monIter_t monIter = _monitors.begin(); monIter != _monitors.end(); monIter++) { try { (*monIter)->beforeMicroStep(shared_from_this()); - } USCXML_MONITOR_CATCH_BLOCK(beforeMicroStep) + } + USCXML_MONITOR_CATCH_BLOCK(beforeMicroStep) } exitStates(enabledTransitions); - + monIter_t monIter; for (int i = 0; i < enabledTransitions.size(); i++) { Element<std::string> transition(enabledTransitions[i]); @@ -630,26 +646,29 @@ void InterpreterDraft6::microstep(const Arabica::XPath::NodeSet<std::string>& en for(monIter_t monIter = _monitors.begin(); monIter != _monitors.end(); monIter++) { try { (*monIter)->beforeTakingTransition(shared_from_this(), transition, (i + 1 < enabledTransitions.size())); - } USCXML_MONITOR_CATCH_BLOCK(beforeTakingTransitions) + } + USCXML_MONITOR_CATCH_BLOCK(beforeTakingTransitions) } - + executeContent(transition); - + // --- MONITOR: afterTakingTransitions ------------------------------ for(monIter_t monIter = _monitors.begin(); monIter != _monitors.end(); monIter++) { try { (*monIter)->afterTakingTransition(shared_from_this(), transition, (i + 1 < enabledTransitions.size())); - } USCXML_MONITOR_CATCH_BLOCK(afterTakingTransitions) + } + USCXML_MONITOR_CATCH_BLOCK(afterTakingTransitions) } } enterStates(enabledTransitions); - + // --- MONITOR: afterMicroStep ------------------------------ for(monIter_t monIter = _monitors.begin(); monIter != _monitors.end(); monIter++) { try { (*monIter)->afterMicroStep(shared_from_this()); - } USCXML_MONITOR_CATCH_BLOCK(afterMicroStep) + } + USCXML_MONITOR_CATCH_BLOCK(afterMicroStep) } } @@ -660,11 +679,11 @@ void InterpreterDraft6::exitInterpreter() { statesToExit.sort(); for (int i = 0; i < statesToExit.size(); i++) { - Arabica::XPath::NodeSet<std::string> onExitElems = filterChildElements(_xmlNSPrefix + "onexit", statesToExit[i]); + Arabica::XPath::NodeSet<std::string> onExitElems = filterChildElements(_nsInfo.xmlNSPrefix + "onexit", statesToExit[i]); for (int j = 0; j < onExitElems.size(); j++) { executeContent(onExitElems[j]); } - Arabica::XPath::NodeSet<std::string> invokeElems = filterChildElements(_xmlNSPrefix + "invoke", statesToExit[i]); + Arabica::XPath::NodeSet<std::string> invokeElems = filterChildElements(_nsInfo.xmlNSPrefix + "invoke", statesToExit[i]); // TODO: we ought to cancel all remaining invokers just to be sure with the persist extension for (int j = 0; j < invokeElems.size(); j++) { cancelInvoke(invokeElems[j]); @@ -750,7 +769,7 @@ void InterpreterDraft6::exitStates(const Arabica::XPath::NodeSet<std::string>& e #endif for (int i = 0; i < statesToExit.size(); i++) { - NodeSet<std::string> histories = filterChildElements(_xmlNSPrefix + "history", statesToExit[i]); + NodeSet<std::string> histories = filterChildElements(_nsInfo.xmlNSPrefix + "history", statesToExit[i]); for (int j = 0; j < histories.size(); j++) { Element<std::string> historyElem = (Element<std::string>)histories[j]; std::string historyType = (historyElem.hasAttribute("type") ? historyElem.getAttribute("type") : "shallow"); @@ -781,23 +800,25 @@ void InterpreterDraft6::exitStates(const Arabica::XPath::NodeSet<std::string>& e for(monIter_t monIter = _monitors.begin(); monIter != _monitors.end(); monIter++) { try { (*monIter)->beforeExitingState(shared_from_this(), Element<std::string>(statesToExit[i]), (i + 1 < statesToExit.size())); - } USCXML_MONITOR_CATCH_BLOCK(beforeExitingState) + } + USCXML_MONITOR_CATCH_BLOCK(beforeExitingState) } - NodeSet<std::string> onExits = filterChildElements(_xmlNSPrefix + "onExit", statesToExit[i]); + NodeSet<std::string> onExits = filterChildElements(_nsInfo.xmlNSPrefix + "onExit", statesToExit[i]); for (int j = 0; j < onExits.size(); j++) { Element<std::string> onExitElem = (Element<std::string>)onExits[j]; executeContent(onExitElem); } - + // --- MONITOR: afterExitingState ------------------------------ for(monIter_t monIter = _monitors.begin(); monIter != _monitors.end(); monIter++) { try { (*monIter)->afterExitingState(shared_from_this(), Element<std::string>(statesToExit[i]), (i + 1 < statesToExit.size())); - } USCXML_MONITOR_CATCH_BLOCK(afterExitingState) + } + USCXML_MONITOR_CATCH_BLOCK(afterExitingState) } - NodeSet<std::string> invokes = filterChildElements(_xmlNSPrefix + "invoke", statesToExit[i]); + NodeSet<std::string> invokes = filterChildElements(_nsInfo.xmlNSPrefix + "invoke", statesToExit[i]); for (int j = 0; j < invokes.size(); j++) { Element<std::string> invokeElem = (Element<std::string>)invokes[j]; if (HAS_ATTR(invokeElem, "persist") && DOMUtils::attributeIsTrue(ATTR(invokeElem, "persist"))) { @@ -806,7 +827,7 @@ void InterpreterDraft6::exitStates(const Arabica::XPath::NodeSet<std::string>& e cancelInvoke(invokeElem); } } - + // remove statesToExit[i] from _configuration - test409 tmp.clear(); for (int j = 0; j < _configuration.size(); j++) { @@ -932,10 +953,10 @@ void InterpreterDraft6::enterStates(const Arabica::XPath::NodeSet<std::string>& for (int i = 0; i < statesToEnter.size(); i++) { Element<std::string> stateElem = (Element<std::string>)statesToEnter[i]; - + // extension for flattened interpreters for (unsigned int k = 0; k < statesToEnter.size(); k++) { - NodeSet<std::string> invokes = filterChildElements(_xmlNSPrefix + "invoke", statesToEnter[k]); + NodeSet<std::string> invokes = filterChildElements(_nsInfo.xmlNSPrefix + "invoke", statesToEnter[k]); for (unsigned int j = 0; j < invokes.size(); j++) { if (HAS_ATTR(invokes[j], "persist") && DOMUtils::attributeIsTrue(ATTR(invokes[j], "persist"))) { invoke(invokes[j]); @@ -947,11 +968,12 @@ void InterpreterDraft6::enterStates(const Arabica::XPath::NodeSet<std::string>& for(monIter_t monIter = _monitors.begin(); monIter != _monitors.end(); monIter++) { try { (*monIter)->beforeEnteringState(shared_from_this(), stateElem, (i + 1 < statesToEnter.size())); - } USCXML_MONITOR_CATCH_BLOCK(beforeEnteringState) + } + USCXML_MONITOR_CATCH_BLOCK(beforeEnteringState) } // extension for flattened SCXML documents, we will need an explicit uninvoke element - NodeSet<std::string> uninvokes = filterChildElements(_xmlNSPrefix + "uninvoke", statesToEnter[i]); + NodeSet<std::string> uninvokes = filterChildElements(_nsInfo.xmlNSPrefix + "uninvoke", statesToEnter[i]); for (int j = 0; j < uninvokes.size(); j++) { Element<std::string> uninvokeElem = (Element<std::string>)uninvokes[j]; cancelInvoke(uninvokeElem); @@ -962,9 +984,9 @@ void InterpreterDraft6::enterStates(const Arabica::XPath::NodeSet<std::string>& // if (_binding == LATE && stateElem.getAttribute("isFirstEntry").size() > 0) { if (_binding == LATE && !isMember(stateElem, _alreadyEntered)) { - NodeSet<std::string> dataModelElems = filterChildElements(_xmlNSPrefix + "datamodel", stateElem); + NodeSet<std::string> dataModelElems = filterChildElements(_nsInfo.xmlNSPrefix + "datamodel", stateElem); if(dataModelElems.size() > 0 && _dataModel) { - Arabica::XPath::NodeSet<std::string> dataElems = filterChildElements(_xmlNSPrefix + "data", dataModelElems[0]); + Arabica::XPath::NodeSet<std::string> dataElems = filterChildElements(_nsInfo.xmlNSPrefix + "data", dataModelElems[0]); for (int j = 0; j < dataElems.size(); j++) { if (dataElems[j].getNodeType() == Node_base::ELEMENT_NODE) initializeData(Element<std::string>(dataElems[j])); @@ -974,24 +996,25 @@ void InterpreterDraft6::enterStates(const Arabica::XPath::NodeSet<std::string>& // stateElem.setAttribute("isFirstEntry", ""); } // execute onentry executable content - NodeSet<std::string> onEntryElems = filterChildElements(_xmlNSPrefix + "onEntry", stateElem); + NodeSet<std::string> onEntryElems = filterChildElements(_nsInfo.xmlNSPrefix + "onEntry", stateElem); executeContent(onEntryElems, false); // --- MONITOR: afterEnteringState ------------------------------ for(monIter_t monIter = _monitors.begin(); monIter != _monitors.end(); monIter++) { try { (*monIter)->afterEnteringState(shared_from_this(), stateElem, (i + 1 < statesToEnter.size())); - } USCXML_MONITOR_CATCH_BLOCK(afterEnteringState) + } + USCXML_MONITOR_CATCH_BLOCK(afterEnteringState) } if (isMember(stateElem, statesForDefaultEntry)) { // execute initial transition content for compound states - Arabica::XPath::NodeSet<std::string> transitions = _xpath.evaluate("" + _xpathPrefix + "initial/" + _xpathPrefix + "transition", stateElem).asNodeSet(); + Arabica::XPath::NodeSet<std::string> transitions = _xpath.evaluate("" + _nsInfo.xpathPrefix + "initial/" + _nsInfo.xpathPrefix + "transition", stateElem).asNodeSet(); for (int j = 0; j < transitions.size(); j++) { executeContent(transitions[j]); } } - + if (isFinal(stateElem)) { internalDoneSend(stateElem); Element<std::string> parent = (Element<std::string>)stateElem.getParentNode(); @@ -1059,7 +1082,7 @@ void InterpreterDraft6::addStatesToEnter(const Node<std::string>& state, } } } else { - NodeSet<std::string> transitions = filterChildElements(_xmlNSPrefix + "transition", state); + NodeSet<std::string> transitions = filterChildElements(_nsInfo.xmlNSPrefix + "transition", state); for (int i = 0; i < transitions.size(); i++) { NodeSet<std::string> targets = getTargetStates(transitions[i]); for (int j = 0; j < targets.size(); j++) { diff --git a/src/uscxml/interpreter/InterpreterRC.cpp b/src/uscxml/interpreter/InterpreterRC.cpp index 52b36e0..10c41d0 100644 --- a/src/uscxml/interpreter/InterpreterRC.cpp +++ b/src/uscxml/interpreter/InterpreterRC.cpp @@ -50,17 +50,17 @@ void InterpreterRC::interpret() { tthread::lock_guard<tthread::recursive_mutex> lock(_mutex); if (!_isInitialized) init(); - + if (!_scxml) { return; } // dump(); - + // just make sure we have a session id assert(_sessionId.length() > 0); - + setupIOProcessors(); - + std::string datamodelName; if (datamodelName.length() == 0 && HAS_ATTR(_scxml, "datamodel")) datamodelName = ATTR(_scxml, "datamodel"); @@ -79,79 +79,89 @@ void InterpreterRC::interpret() { if(datamodelName.length() > 0 && !_dataModel) { LOG(ERROR) << "No datamodel for " << datamodelName << " registered"; } - + if (_dataModel) { _dataModel.assign("_x.args", _cmdLineOptions); } - + _running = true; _binding = (HAS_ATTR(_scxml, "binding") && iequals(ATTR(_scxml, "binding"), "late") ? LATE : EARLY); - + // @TODO: Reread http://www.w3.org/TR/scxml/#DataBinding - + if (_dataModel && _binding == EARLY) { // initialize all data elements - NodeSet<std::string> dataElems = _xpath.evaluate("//" + _xpathPrefix + "data", _scxml).asNodeSet(); + NodeSet<std::string> dataElems = _xpath.evaluate("//" + _nsInfo.xpathPrefix + "data", _scxml).asNodeSet(); for (unsigned int i = 0; i < dataElems.size(); i++) { // do not process data elements of nested documents from invokers - if (!getAncestorElement(dataElems[i], _xmlNSPrefix + "invoke")) + if (!getAncestorElement(dataElems[i], _nsInfo.xmlNSPrefix + "invoke")) if (dataElems[i].getNodeType() == Node_base::ELEMENT_NODE) { initializeData(Element<std::string>(dataElems[i])); } } } else if(_dataModel) { // initialize current data elements - NodeSet<std::string> topDataElems = filterChildElements(_xmlNSPrefix + "data", filterChildElements(_xmlNSPrefix + "datamodel", _scxml)); + NodeSet<std::string> topDataElems = filterChildElements(_nsInfo.xmlNSPrefix + "data", filterChildElements(_nsInfo.xmlNSPrefix + "datamodel", _scxml)); for (unsigned int i = 0; i < topDataElems.size(); i++) { if (topDataElems[i].getNodeType() == Node_base::ELEMENT_NODE) initializeData(Element<std::string>(topDataElems[i])); } } - + // executeGlobalScriptElements - NodeSet<std::string> globalScriptElems = filterChildElements(_xmlNSPrefix + "script", _scxml); + NodeSet<std::string> globalScriptElems = filterChildElements(_nsInfo.xmlNSPrefix + "script", _scxml); for (unsigned int i = 0; i < globalScriptElems.size(); i++) { if (_dataModel) { executeContent(globalScriptElems[i]); } } - + NodeSet<std::string> initialTransitions; - + if (_userDefinedStartConfiguration.size() > 0) { // we emulate entering a given configuration by creating a pseudo deep history - Element<std::string> initHistory = _document.createElementNS(_nsURL, "history"); + Element<std::string> initHistory = _document.createElementNS(_nsInfo.nsURL, "history"); + _nsInfo.setPrefix(initHistory); + initHistory.setAttribute("id", UUID::getUUID()); initHistory.setAttribute("type", "deep"); _scxml.insertBefore(initHistory, _scxml.getFirstChild()); - + std::string histId = ATTR(initHistory, "id"); NodeSet<std::string> histStates; for (int i = 0; i < _userDefinedStartConfiguration.size(); i++) { histStates.push_back(getState(_userDefinedStartConfiguration[i])); } _historyValue[histId] = histStates; - - Element<std::string> initialElem = _document.createElementNS(_nsURL, "initial"); + + Element<std::string> initialElem = _document.createElementNS(_nsInfo.nsURL, "initial"); + _nsInfo.setPrefix(initialElem); + initialElem.setAttribute("generated", "true"); - Element<std::string> transitionElem = _document.createElementNS(_nsURL, "transition"); + Element<std::string> transitionElem = _document.createElementNS(_nsInfo.nsURL, "transition"); + _nsInfo.setPrefix(transitionElem); + transitionElem.setAttribute("target", histId); initialElem.appendChild(transitionElem); _scxml.appendChild(initialElem); initialTransitions.push_back(transitionElem); - + } else { // try to get initial transition from initial element - initialTransitions = _xpath.evaluate("/" + _xpathPrefix + "initial/" + _xpathPrefix + "transition", _scxml).asNodeSet(); + initialTransitions = _xpath.evaluate("/" + _nsInfo.xpathPrefix + "initial/" + _nsInfo.xpathPrefix + "transition", _scxml).asNodeSet(); if (initialTransitions.size() == 0) { Arabica::XPath::NodeSet<std::string> initialStates; // fetch per draft initialStates = getInitialStates(); assert(initialStates.size() > 0); for (int i = 0; i < initialStates.size(); i++) { - Element<std::string> initialElem = _document.createElementNS(_nsURL, "initial"); + Element<std::string> initialElem = _document.createElementNS(_nsInfo.nsURL, "initial"); + _nsInfo.setPrefix(initialElem); + initialElem.setAttribute("generated", "true"); - Element<std::string> transitionElem = _document.createElementNS(_nsURL, "transition"); + Element<std::string> transitionElem = _document.createElementNS(_nsInfo.nsURL, "transition"); + _nsInfo.setPrefix(transitionElem); + transitionElem.setAttribute("target", ATTR(initialStates[i], "id")); initialElem.appendChild(transitionElem); _scxml.appendChild(initialElem); @@ -159,12 +169,12 @@ void InterpreterRC::interpret() { } } } - + assert(initialTransitions.size() > 0); - + enterStates(initialTransitions); // _mutex.unlock(); - + // assert(hasLegalConfiguration()); mainEventLoop(); } catch (boost::bad_weak_ptr e) { @@ -173,7 +183,7 @@ void InterpreterRC::interpret() { // set datamodel to null from this thread if(_dataModel) _dataModel = DataModel(); - + } /** @@ -181,12 +191,12 @@ procedure mainEventLoop(): while running: enabledTransitions = null macrostepDone = false - # Here we handle eventless transitions and transitions + # Here we handle eventless transitions and transitions # triggered by internal events until macrostep is complete while running and not macrostepDone: enabledTransitions = selectEventlessTransitions() if enabledTransitions.isEmpty(): - if internalQueue.isEmpty(): + if internalQueue.isEmpty(): macrostepDone = true else: internalEvent = internalQueue.dequeue() @@ -194,7 +204,7 @@ procedure mainEventLoop(): enabledTransitions = selectTransitions(internalEvent) if not enabledTransitions.isEmpty(): microstep(enabledTransitions.toList()) - # either we're in a final state, and we break out of the loop + # either we're in a final state, and we break out of the loop if not running: break; # or we've completed a macrostep, so we start a new macrostep by waiting for an external event @@ -203,7 +213,7 @@ procedure mainEventLoop(): for inv in state.invoke: invoke(inv) statesToInvoke.clear() - # Invoking may have raised internal error events and we iterate to handle them + # Invoking may have raised internal error events and we iterate to handle them if not internalQueue.isEmpty(): continue # A blocking wait for an external event. Alternatively, if we have been invoked @@ -219,24 +229,24 @@ procedure mainEventLoop(): if inv.invokeid == externalEvent.invokeid: applyFinalize(inv, externalEvent) if inv.autoforward: - send(inv.id, externalEvent) + send(inv.id, externalEvent) enabledTransitions = selectTransitions(externalEvent) if not enabledTransitions.isEmpty(): - microstep(enabledTransitions.toList()) - # End of outer while running loop. If we get here, we have reached a top-level final state or have been cancelled - exitInterpreter() + microstep(enabledTransitions.toList()) + # End of outer while running loop. If we get here, we have reached a top-level final state or have been cancelled + exitInterpreter() */ void InterpreterRC::mainEventLoop() { monIter_t monIter; - + while(_running) { NodeSet<std::string> enabledTransitions; _stable = false; - + // Here we handle eventless transitions and transitions // triggered by internal events until machine is stable while(_running && !_stable) { - + enabledTransitions = selectEventlessTransitions(); if (enabledTransitions.size() == 0) { if (_internalQueue.size() == 0) { @@ -244,14 +254,15 @@ void InterpreterRC::mainEventLoop() { } else { _currEvent = _internalQueue.front(); _internalQueue.pop_front(); - + // --- MONITOR: beforeProcessingEvent ------------------------------ for(monIter_t monIter = _monitors.begin(); monIter != _monitors.end(); monIter++) { try { (*monIter)->beforeProcessingEvent(shared_from_this(), _currEvent); - } USCXML_MONITOR_CATCH_BLOCK(beforeProcessingEvent) + } + USCXML_MONITOR_CATCH_BLOCK(beforeProcessingEvent) } - + if (_dataModel) _dataModel.setEvent(_currEvent); enabledTransitions = selectTransitions(_currEvent.name); @@ -263,12 +274,12 @@ void InterpreterRC::mainEventLoop() { microstep(enabledTransitions); } } - + if (!_running) goto EXIT_INTERPRETER; for (unsigned int i = 0; i < _statesToInvoke.size(); i++) { - NodeSet<std::string> invokes = filterChildElements(_xmlNSPrefix + "invoke", _statesToInvoke[i]); + NodeSet<std::string> invokes = filterChildElements(_nsInfo.xmlNSPrefix + "invoke", _statesToInvoke[i]); for (unsigned int j = 0; j < invokes.size(); j++) { invoke(invokes[j]); } @@ -277,7 +288,7 @@ void InterpreterRC::mainEventLoop() { if (!_internalQueue.empty()) continue; - + // assume that we have a legal configuration as soon as the internal queue is empty if (!hasLegalConfiguration()) { std::cout << "Illegal configuration!" << std::endl; @@ -287,26 +298,27 @@ void InterpreterRC::mainEventLoop() { std::cout << std::endl; } assert(hasLegalConfiguration()); - + monIter = _monitors.begin(); // if (!_sendQueue || _sendQueue->isEmpty()) { - + // --- MONITOR: onStableConfiguration ------------------------------ for(monIter_t monIter = _monitors.begin(); monIter != _monitors.end(); monIter++) { try { (*monIter)->onStableConfiguration(shared_from_this()); - } USCXML_MONITOR_CATCH_BLOCK(onStableConfiguration) + } + USCXML_MONITOR_CATCH_BLOCK(onStableConfiguration) } - + // } - + _mutex.unlock(); // whenever we have a stable configuration, run the mainThread hooks with 200fps while(_externalQueue.isEmpty() && _thread == NULL) { runOnMainThread(200); } _mutex.lock(); - + // A blocking wait for an external event. Alternatively, if we have been invoked // our parent session also might cancel us. The mechanism for this is platform specific, // but here we assume it's a special event we receive @@ -321,17 +333,18 @@ void InterpreterRC::mainEventLoop() { _currEvent.eventType = Event::EXTERNAL; // make sure it is set to external if (!_running) goto EXIT_INTERPRETER; - + // --- MONITOR: beforeProcessingEvent ------------------------------ for(monIter_t monIter = _monitors.begin(); monIter != _monitors.end(); monIter++) { try { (*monIter)->beforeProcessingEvent(shared_from_this(), _currEvent); - } USCXML_MONITOR_CATCH_BLOCK(beforeProcessingEvent) + } + USCXML_MONITOR_CATCH_BLOCK(beforeProcessingEvent) } - + if (_dataModel && iequals(_currEvent.name, "cancel.invoke." + _sessionId)) break; - + if (_dataModel) { try { _dataModel.setEvent(_currEvent); @@ -340,7 +353,7 @@ void InterpreterRC::mainEventLoop() { } } for (unsigned int i = 0; i < _configuration.size(); i++) { - NodeSet<std::string> invokes = filterChildElements(_xmlNSPrefix + "invoke", _configuration[i]); + NodeSet<std::string> invokes = filterChildElements(_nsInfo.xmlNSPrefix + "invoke", _configuration[i]); for (unsigned int j = 0; j < invokes.size(); j++) { Element<std::string> invokeElem = (Element<std::string>)invokes[j]; std::string invokeId; @@ -357,13 +370,13 @@ void InterpreterRC::mainEventLoop() { } std::string autoForward = invokeElem.getAttribute("autoforward"); if (iequals(invokeId, _currEvent.invokeid)) { - - Arabica::XPath::NodeSet<std::string> finalizes = filterChildElements(_xmlNSPrefix + "finalize", invokeElem); + + Arabica::XPath::NodeSet<std::string> finalizes = filterChildElements(_nsInfo.xmlNSPrefix + "finalize", invokeElem); for (int k = 0; k < finalizes.size(); k++) { Element<std::string> finalizeElem = Element<std::string>(finalizes[k]); executeContent(finalizeElem); } - + } if (iequals(autoForward, "true")) { try { @@ -384,15 +397,16 @@ void InterpreterRC::mainEventLoop() { microstep(enabledTransitions); } } - + EXIT_INTERPRETER: // --- MONITOR: beforeCompletion ------------------------------ for(monIter_t monIter = _monitors.begin(); monIter != _monitors.end(); monIter++) { try { (*monIter)->beforeCompletion(shared_from_this()); - } USCXML_MONITOR_CATCH_BLOCK(beforeCompletion) + } + USCXML_MONITOR_CATCH_BLOCK(beforeCompletion) } - + exitInterpreter(); if (_sendQueue) { std::map<std::string, std::pair<InterpreterImpl*, SendRequest> >::iterator sendIter = _sendIds.begin(); @@ -401,14 +415,15 @@ EXIT_INTERPRETER: sendIter++; } } - + // --- MONITOR: afterCompletion ------------------------------ for(monIter_t monIter = _monitors.begin(); monIter != _monitors.end(); monIter++) { try { (*monIter)->afterCompletion(shared_from_this()); - } USCXML_MONITOR_CATCH_BLOCK(afterCompletion) + } + USCXML_MONITOR_CATCH_BLOCK(afterCompletion) } - + } /** @@ -420,7 +435,7 @@ procedure exitInterpreter(): for inv in s.invoke: cancelInvoke(inv) configuration.delete(s) - if isFinalState(s) and isScxmlState(s.parent): + if isFinalState(s) and isScxmlState(s.parent): returnDoneEvent(s.donedata) */ void InterpreterRC::exitInterpreter() { @@ -429,11 +444,11 @@ void InterpreterRC::exitInterpreter() { statesToExit.sort(); for (int i = 0; i < statesToExit.size(); i++) { - Arabica::XPath::NodeSet<std::string> onExitElems = filterChildElements(_xmlNSPrefix + "onexit", statesToExit[i]); + Arabica::XPath::NodeSet<std::string> onExitElems = filterChildElements(_nsInfo.xmlNSPrefix + "onexit", statesToExit[i]); for (int j = 0; j < onExitElems.size(); j++) { executeContent(onExitElems[j]); } - Arabica::XPath::NodeSet<std::string> invokeElems = filterChildElements(_xmlNSPrefix + "invoke", statesToExit[i]); + Arabica::XPath::NodeSet<std::string> invokeElems = filterChildElements(_nsInfo.xmlNSPrefix + "invoke", statesToExit[i]); for (int j = 0; j < invokeElems.size(); j++) { cancelInvoke(invokeElems[j]); } @@ -451,7 +466,7 @@ function selectEventlessTransitions(): for state in atomicStates: loop: for s in [state].append(getProperAncestors(state, null)): for t in s.transition: - if not t.event and conditionMatch(t): + if not t.event and conditionMatch(t): enabledTransitions.add(t) break loop enabledTransitions = removeConflictingTransitions(enabledTransitions) @@ -459,7 +474,7 @@ function selectEventlessTransitions(): */ Arabica::XPath::NodeSet<std::string> InterpreterRC::selectEventlessTransitions() { Arabica::XPath::NodeSet<std::string> enabledTransitions; - + NodeSet<std::string> atomicStates; for (unsigned int i = 0; i < _configuration.size(); i++) { if (isAtomic(_configuration[i])) @@ -474,7 +489,7 @@ Arabica::XPath::NodeSet<std::string> InterpreterRC::selectEventlessTransitions() withAncestors.push_back(getProperAncestors(state, Node<std::string>())); for (unsigned int j = 0; j < withAncestors.size(); j++) { const Node<std::string>& ancestor = withAncestors[i]; - NodeSet<std::string> transitions = filterChildElements(_xmlNSPrefix + "transition", ancestor); + NodeSet<std::string> transitions = filterChildElements(_nsInfo.xmlNSPrefix + "transition", ancestor); for (unsigned int k = 0; k < transitions.size(); k++) { if (!HAS_ATTR(transitions[k], "event") && hasConditionMatch(transitions[k])) { enabledTransitions.push_back(transitions[k]); @@ -482,9 +497,10 @@ Arabica::XPath::NodeSet<std::string> InterpreterRC::selectEventlessTransitions() } } } - BREAK_LOOP:; +BREAK_LOOP: + ; } - + enabledTransitions = removeConflictingTransitions(enabledTransitions); return enabledTransitions; } @@ -504,14 +520,14 @@ function selectTransitions(event): */ Arabica::XPath::NodeSet<std::string> InterpreterRC::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(_configuration[i])) atomicStates.push_back(_configuration[i]); } atomicStates.to_document_order(); - + #if 0 std::cout << "selectTransitions for " << event << "========" << std::endl; #endif @@ -520,13 +536,13 @@ Arabica::XPath::NodeSet<std::string> InterpreterRC::selectTransitions(const std: #if 0 std::cout << " == from " << ATTR(state, "id") << std::endl; #endif - + NodeSet<std::string> withAncestors; withAncestors.push_back(state); withAncestors.push_back(getProperAncestors(state, Node<std::string>())); for (unsigned int j = 0; j < withAncestors.size(); j++) { const Node<std::string>& ancestor = withAncestors[j]; - NodeSet<std::string> transitions = filterChildElements(_xmlNSPrefix + "transition", ancestor); + NodeSet<std::string> transitions = filterChildElements(_nsInfo.xmlNSPrefix + "transition", ancestor); for (unsigned int k = 0; k < transitions.size(); k++) { if (isEnabledTransition(transitions[k], event)) { enabledTransitions.push_back(transitions[k]); @@ -534,9 +550,10 @@ Arabica::XPath::NodeSet<std::string> InterpreterRC::selectTransitions(const std: } } } - BREAK_LOOP:; +BREAK_LOOP: + ; } - + enabledTransitions = removeConflictingTransitions(enabledTransitions); #if 0 @@ -564,7 +581,7 @@ bool InterpreterRC::isEnabledTransition(const Node<std::string>& transition, con } else { return false; } - + std::list<std::string> eventNames = tokenizeIdRefs(eventName); std::list<std::string>::iterator eventIter = eventNames.begin(); while(eventIter != eventNames.end()) { @@ -588,19 +605,19 @@ function removeConflictingTransitions(enabledTransitions): if computeExitSet([t1]).hasIntersection(computeExitSet([t2])): if isDescendant(t1.source, t2.source): transitionsToRemove.add(t2) - else: + else: t1Preempted = true break if not t1Preempted: for t3 in transitionsToRemove.toList(): filteredTransitions.delete(t3) filteredTransitions.add(t1) - + return filteredTransitions */ Arabica::XPath::NodeSet<std::string> InterpreterRC::removeConflictingTransitions(const Arabica::XPath::NodeSet<std::string>& enabledTransitions) { Arabica::XPath::NodeSet<std::string> filteredTransitions; - + for (unsigned int i = 0; i < enabledTransitions.size(); i++) { const Node<std::string>& t1 = enabledTransitions[i]; bool t1Preempted = false; @@ -617,7 +634,7 @@ Arabica::XPath::NodeSet<std::string> InterpreterRC::removeConflictingTransitions } } } - + if (!t1Preempted) { // remove transitionsToRemove from filteredTransitions std::list<Node<std::string> > tmp; @@ -652,58 +669,62 @@ procedure microstep(enabledTransitions): enterStates(enabledTransitions) */ void InterpreterRC::microstep(const Arabica::XPath::NodeSet<std::string>& enabledTransitions) { - + // --- MONITOR: beforeMicroStep ------------------------------ for(monIter_t monIter = _monitors.begin(); monIter != _monitors.end(); monIter++) { try { (*monIter)->beforeMicroStep(shared_from_this()); - } USCXML_MONITOR_CATCH_BLOCK(beforeMicroStep) + } + USCXML_MONITOR_CATCH_BLOCK(beforeMicroStep) } - + exitStates(enabledTransitions); - + monIter_t monIter; for (int i = 0; i < enabledTransitions.size(); i++) { Element<std::string> transition(enabledTransitions[i]); - + // --- MONITOR: beforeTakingTransitions ------------------------------ for(monIter_t monIter = _monitors.begin(); monIter != _monitors.end(); monIter++) { try { (*monIter)->beforeTakingTransition(shared_from_this(), transition, (i + 1 < enabledTransitions.size())); - } USCXML_MONITOR_CATCH_BLOCK(beforeTakingTransitions) + } + USCXML_MONITOR_CATCH_BLOCK(beforeTakingTransitions) } - + executeContent(transition); - + // --- MONITOR: afterTakingTransitions ------------------------------ for(monIter_t monIter = _monitors.begin(); monIter != _monitors.end(); monIter++) { try { (*monIter)->afterTakingTransition(shared_from_this(), transition, (i + 1 < enabledTransitions.size())); - } USCXML_MONITOR_CATCH_BLOCK(afterTakingTransitions) + } + USCXML_MONITOR_CATCH_BLOCK(afterTakingTransitions) } } - + enterStates(enabledTransitions); - + // --- MONITOR: afterMicroStep ------------------------------ for(monIter_t monIter = _monitors.begin(); monIter != _monitors.end(); monIter++) { try { (*monIter)->afterMicroStep(shared_from_this()); - } USCXML_MONITOR_CATCH_BLOCK(afterMicroStep) + } + USCXML_MONITOR_CATCH_BLOCK(afterMicroStep) } } /** procedure exitStates(enabledTransitions): - statesToExit = computeExitSet(enabledTransitions) + statesToExit = computeExitSet(enabledTransitions) for s in statesToExit: statesToInvoke.delete(s) statesToExit = statesToExit.toList().sort(exitOrder) for s in statesToExit: for h in s.history: if h.type == "deep": - f = lambda s0: isAtomicState(s0) and isDescendant(s0,s) + f = lambda s0: isAtomicState(s0) and isDescendant(s0,s) else: f = lambda s0: s0.parent == s historyValue[h.id] = configuration.toList().filter(f) @@ -730,9 +751,9 @@ void InterpreterRC::exitStates(const Arabica::XPath::NodeSet<std::string>& enabl statesToExit.forward(false); statesToExit.sort(); - + for (int i = 0; i < statesToExit.size(); i++) { - NodeSet<std::string> histories = filterChildElements(_xmlNSPrefix + "history", statesToExit[i]); + NodeSet<std::string> histories = filterChildElements(_nsInfo.xmlNSPrefix + "history", statesToExit[i]); for (int j = 0; j < histories.size(); j++) { Element<std::string> historyElem = (Element<std::string>)histories[j]; std::string historyType = (historyElem.hasAttribute("type") ? historyElem.getAttribute("type") : "shallow"); @@ -749,34 +770,36 @@ void InterpreterRC::exitStates(const Arabica::XPath::NodeSet<std::string>& enabl _historyValue[historyElem.getAttribute("id")] = historyNodes; } } - + for (int i = 0; i < statesToExit.size(); i++) { // --- MONITOR: beforeExitingState ------------------------------ for(monIter_t monIter = _monitors.begin(); monIter != _monitors.end(); monIter++) { try { (*monIter)->beforeExitingState(shared_from_this(), Element<std::string>(statesToExit[i]), (i + 1 < statesToExit.size())); - } USCXML_MONITOR_CATCH_BLOCK(beforeExitingState) + } + USCXML_MONITOR_CATCH_BLOCK(beforeExitingState) } - - NodeSet<std::string> onExits = filterChildElements(_xmlNSPrefix + "onExit", statesToExit[i]); + + NodeSet<std::string> onExits = filterChildElements(_nsInfo.xmlNSPrefix + "onExit", statesToExit[i]); for (int j = 0; j < onExits.size(); j++) { Element<std::string> onExitElem = (Element<std::string>)onExits[j]; executeContent(onExitElem); } - + // --- MONITOR: afterExitingState ------------------------------ for(monIter_t monIter = _monitors.begin(); monIter != _monitors.end(); monIter++) { try { (*monIter)->afterExitingState(shared_from_this(), Element<std::string>(statesToExit[i]), (i + 1 < statesToExit.size())); - } USCXML_MONITOR_CATCH_BLOCK(afterExitingState) + } + USCXML_MONITOR_CATCH_BLOCK(afterExitingState) } - - NodeSet<std::string> invokes = filterChildElements(_xmlNSPrefix + "invoke", statesToExit[i]); + + NodeSet<std::string> invokes = filterChildElements(_nsInfo.xmlNSPrefix + "invoke", statesToExit[i]); for (int j = 0; j < invokes.size(); j++) { Element<std::string> invokeElem = (Element<std::string>)invokes[j]; cancelInvoke(invokeElem); } - + // remove statesToExit[i] from _configuration - test409 tmp.clear(); for (int j = 0; j < _configuration.size(); j++) { @@ -799,7 +822,7 @@ function computeExitSet(transitions) for s in configuration: if isDescendant(s,domain): statesToExit.add(s) - return statesToExit + return statesToExit */ Arabica::XPath::NodeSet<std::string> InterpreterRC::computeExitSet(const Arabica::XPath::NodeSet<std::string>& transitions) { NodeSet<std::string> statesToExit; @@ -832,13 +855,13 @@ Arabica::XPath::NodeSet<std::string> InterpreterRC::computeExitSet(const Arabica transitions.push_back(transition); return computeExitSet(transitions); } - + /** procedure enterStates(enabledTransitions): statesToEnter = new OrderedSet() statesForDefaultEntry = new OrderedSet() - computeEntrySet(enabledTransitions, statesToEnter, statesForDefaultEntry) + computeEntrySet(enabledTransitions, statesToEnter, statesForDefaultEntry) for s in statesToEnter.toList().sort(entryOrder): configuration.add(s) statesToInvoke.add(s) @@ -866,28 +889,29 @@ void InterpreterRC::enterStates(const Arabica::XPath::NodeSet<std::string>& enab // initialize the temporary table for default content in history states std::map<std::string, Arabica::DOM::Node<std::string> > defaultHistoryContent; monIter_t monIter; - + computeEntrySet(enabledTransitions, statesToEnter, statesForDefaultEntry, defaultHistoryContent); statesToEnter.to_document_order(); - + for (int i = 0; i < statesToEnter.size(); i++) { Element<std::string> s = (Element<std::string>)statesToEnter[i]; - + // --- MONITOR: beforeEnteringState ------------------------------ for(monIter_t monIter = _monitors.begin(); monIter != _monitors.end(); monIter++) { try { (*monIter)->beforeEnteringState(shared_from_this(), s, (i + 1 < statesToEnter.size())); - } USCXML_MONITOR_CATCH_BLOCK(beforeEnteringState) + } + USCXML_MONITOR_CATCH_BLOCK(beforeEnteringState) } - + _configuration.push_back(s); _statesToInvoke.push_back(s); - + // if (_binding == LATE && stateElem.getAttribute("isFirstEntry").size() > 0) { if (_binding == LATE && !isMember(s, _alreadyEntered)) { - NodeSet<std::string> dataModelElems = filterChildElements(_xmlNSPrefix + "datamodel", s); + NodeSet<std::string> dataModelElems = filterChildElements(_nsInfo.xmlNSPrefix + "datamodel", s); if(dataModelElems.size() > 0 && _dataModel) { - Arabica::XPath::NodeSet<std::string> dataElems = filterChildElements(_xmlNSPrefix + "data", dataModelElems[0]); + Arabica::XPath::NodeSet<std::string> dataElems = filterChildElements(_nsInfo.xmlNSPrefix + "data", dataModelElems[0]); for (int j = 0; j < dataElems.size(); j++) { if (dataElems[j].getNodeType() == Node_base::ELEMENT_NODE) initializeData(Element<std::string>(dataElems[j])); @@ -897,19 +921,20 @@ void InterpreterRC::enterStates(const Arabica::XPath::NodeSet<std::string>& enab // stateElem.setAttribute("isFirstEntry", ""); } // execute onentry executable content - NodeSet<std::string> onEntryElems = filterChildElements(_xmlNSPrefix + "onEntry", s); + NodeSet<std::string> onEntryElems = filterChildElements(_nsInfo.xmlNSPrefix + "onEntry", s); executeContent(onEntryElems, false); - + // --- MONITOR: afterEnteringState ------------------------------ for(monIter_t monIter = _monitors.begin(); monIter != _monitors.end(); monIter++) { try { (*monIter)->afterEnteringState(shared_from_this(), s, (i + 1 < statesToEnter.size())); - } USCXML_MONITOR_CATCH_BLOCK(afterEnteringState) + } + USCXML_MONITOR_CATCH_BLOCK(afterEnteringState) } - + if (isMember(s, statesForDefaultEntry)) { // execute initial transition content for compound states - Arabica::XPath::NodeSet<std::string> transitions = _xpath.evaluate("" + _xpathPrefix + "initial/" + _xpathPrefix + "transition", s).asNodeSet(); + Arabica::XPath::NodeSet<std::string> transitions = _xpath.evaluate("" + _nsInfo.xpathPrefix + "initial/" + _nsInfo.xpathPrefix + "transition", s).asNodeSet(); for (int j = 0; j < transitions.size(); j++) { executeContent(transitions[j]); } @@ -917,18 +942,18 @@ void InterpreterRC::enterStates(const Arabica::XPath::NodeSet<std::string>& enab if (defaultHistoryContent.find(ATTR(s, "id")) != defaultHistoryContent.end()) { executeContent(defaultHistoryContent[ATTR(s, "id")]); } - + /** - if isFinalState(s): - if isSCXMLElement(s.parent): - running = false - else: - parent = s.parent - grandparent = parent.parent - internalQueue.enqueue(new Event("done.state." + parent.id, s.donedata)) - if isParallelState(grandparent): - if getChildStates(grandparent).every(isInFinalState): - internalQueue.enqueue(new Event("done.state." + grandparent.id)) + if isFinalState(s): + if isSCXMLElement(s.parent): + running = false + else: + parent = s.parent + grandparent = parent.parent + internalQueue.enqueue(new Event("done.state." + parent.id, s.donedata)) + if isParallelState(grandparent): + if getChildStates(grandparent).every(isInFinalState): + internalQueue.enqueue(new Event("done.state." + grandparent.id)) */ //std::cout << _name << ": " << s << std::endl; @@ -940,9 +965,9 @@ void InterpreterRC::enterStates(const Arabica::XPath::NodeSet<std::string>& enab } else { Element<std::string> parent = (Element<std::string>)s.getParentNode(); Element<std::string> grandParent = (Element<std::string>)parent.getParentNode(); - + internalDoneSend(parent); - + if (isParallel(grandParent)) { Arabica::XPath::NodeSet<std::string> childs = getChildStates(grandParent); bool inFinalState = true; @@ -965,18 +990,18 @@ void InterpreterRC::enterStates(const Arabica::XPath::NodeSet<std::string>& enab /** procedure computeEntrySet(transitions, statesToEnter, statesForDefaultEntry) for t in transitions: - statesToEnter.union(getTargetStates(t.target)) + statesToEnter.union(getTargetStates(t.target)) for s in statesToEnter: - addDescendantStatesToEnter(s,statesToEnter,statesForDefaultEntry) - for t in transitions: - ancestor = getTransitionDomain(t) - for s in getTargetStates(t.target)): + addDescendantStatesToEnter(s,statesToEnter,statesForDefaultEntry) + for t in transitions: + ancestor = getTransitionDomain(t) + for s in getTargetStates(t.target)): addAncestorStatesToEnter(s, ancestor, statesToEnter, statesForDefaultEntry) */ void InterpreterRC::computeEntrySet(const Arabica::XPath::NodeSet<std::string>& transitions, - NodeSet<std::string>& statesToEnter, - NodeSet<std::string>& statesForDefaultEntry, - std::map<std::string, Arabica::DOM::Node<std::string> > defaultHistoryContent) { + NodeSet<std::string>& statesToEnter, + NodeSet<std::string>& statesForDefaultEntry, + std::map<std::string, Arabica::DOM::Node<std::string> > defaultHistoryContent) { for (int i = 0; i < transitions.size(); i++) { const Node<std::string>& t = transitions[i]; @@ -1001,7 +1026,7 @@ void InterpreterRC::computeEntrySet(const Arabica::XPath::NodeSet<std::string>& assert(tmp[i]); addDescendantStatesToEnter(tmp[i],statesToEnter,statesForDefaultEntry, defaultHistoryContent); } - + #if 1 std::cout << "after addDescendantStatesToEnter: "; for (int i = 0; i < statesToEnter.size(); i++) { @@ -1009,7 +1034,7 @@ void InterpreterRC::computeEntrySet(const Arabica::XPath::NodeSet<std::string>& } std::cout << std::endl; #endif - + for (int i = 0; i < transitions.size(); i++) { Element<std::string> t = (Element<std::string>)transitions[i]; Node<std::string> ancestor = getTransitionDomain(t); @@ -1030,9 +1055,9 @@ void InterpreterRC::computeEntrySet(const Arabica::XPath::NodeSet<std::string>& } void InterpreterRC::computeEntrySet(const Arabica::DOM::Node<std::string>& transition, - NodeSet<std::string>& statesToEnter, - NodeSet<std::string>& statesForDefaultEntry, - std::map<std::string, Arabica::DOM::Node<std::string> > defaultHistoryContent) { + NodeSet<std::string>& statesToEnter, + NodeSet<std::string>& statesForDefaultEntry, + std::map<std::string, Arabica::DOM::Node<std::string> > defaultHistoryContent) { Arabica::XPath::NodeSet<std::string> transitions; transitions.push_back(transition); computeEntrySet(transitions, statesToEnter, statesForDefaultEntry, defaultHistoryContent); @@ -1062,12 +1087,12 @@ procedure addDescendantStatesToEnter(state,statesToEnter,statesForDefaultEntry): if isParallelState(state): for child in getChildStates(state): if not statesToEnter.some(lambda s: isDescendant(s,child)): - addDescendantStatesToEnter(child,statesToEnter,statesForDefaultEntry) + addDescendantStatesToEnter(child,statesToEnter,statesForDefaultEntry) */ void InterpreterRC::addDescendantStatesToEnter(const Arabica::DOM::Node<std::string>& state, - Arabica::XPath::NodeSet<std::string>& statesToEnter, - Arabica::XPath::NodeSet<std::string>& statesForDefaultEntry, - std::map<std::string, Arabica::DOM::Node<std::string> > defaultHistoryContent) { + Arabica::XPath::NodeSet<std::string>& statesToEnter, + Arabica::XPath::NodeSet<std::string>& statesForDefaultEntry, + std::map<std::string, Arabica::DOM::Node<std::string> > defaultHistoryContent) { if (isHistory(state)) { std::string stateId = ATTR(state, "id"); if (_historyValue.find(stateId) != _historyValue.end()) { @@ -1078,7 +1103,7 @@ void InterpreterRC::addDescendantStatesToEnter(const Arabica::DOM::Node<std::str addAncestorStatesToEnter(s, getParentState(s), statesToEnter, statesForDefaultEntry, defaultHistoryContent); } } else { - NodeSet<std::string> transitions = filterChildElements(_xmlNSPrefix + "transition", state); + NodeSet<std::string> transitions = filterChildElements(_nsInfo.xmlNSPrefix + "transition", state); if (transitions.size() > 0) { defaultHistoryContent[ATTR(state, "id")] = transitions[0]; } @@ -1097,7 +1122,7 @@ void InterpreterRC::addDescendantStatesToEnter(const Arabica::DOM::Node<std::str } else { if (!isMember(state, statesToEnter)) // adding an existing element invalidates old reference statesToEnter.push_back(state); - + if (isCompound(state)) { statesForDefaultEntry.push_back(state); NodeSet<std::string> targets = getInitialStates(state); @@ -1119,7 +1144,8 @@ void InterpreterRC::addDescendantStatesToEnter(const Arabica::DOM::Node<std::str } } addDescendantStatesToEnter(child,statesToEnter,statesForDefaultEntry, defaultHistoryContent); - BREAK_LOOP:; +BREAK_LOOP: + ; } } } @@ -1133,13 +1159,13 @@ procedure addAncestorStatesToEnter(state, ancestor, statesToEnter, statesForDefa if isParallelState(anc): for child in getChildStates(anc): if not statesToEnter.some(lambda s: isDescendant(s,child)): - addDescendantStatesToEnter(child,statesToEnter,statesForDefaultEntry) + addDescendantStatesToEnter(child,statesToEnter,statesForDefaultEntry) */ void InterpreterRC::addAncestorStatesToEnter(const Arabica::DOM::Node<std::string>& state, - const Arabica::DOM::Node<std::string>& ancestor, - Arabica::XPath::NodeSet<std::string>& statesToEnter, - Arabica::XPath::NodeSet<std::string>& statesForDefaultEntry, - std::map<std::string, Arabica::DOM::Node<std::string> > defaultHistoryContent) { + const Arabica::DOM::Node<std::string>& ancestor, + Arabica::XPath::NodeSet<std::string>& statesToEnter, + Arabica::XPath::NodeSet<std::string>& statesForDefaultEntry, + std::map<std::string, Arabica::DOM::Node<std::string> > defaultHistoryContent) { NodeSet<std::string> ancestors = getProperAncestors(state,ancestor); for (int i = 0; i < ancestors.size(); i++) { const Node<std::string>& anc = ancestors[i]; @@ -1155,7 +1181,8 @@ void InterpreterRC::addAncestorStatesToEnter(const Arabica::DOM::Node<std::strin } } addDescendantStatesToEnter(child,statesToEnter,statesForDefaultEntry, defaultHistoryContent); - BREAK_LOOP:; +BREAK_LOOP: + ; } } } @@ -1202,16 +1229,16 @@ function getTransitionDomain(t) Arabica::DOM::Node<std::string> InterpreterRC::getTransitionDomain(const Arabica::DOM::Node<std::string>& transition) { NodeSet<std::string> tStates = getTargetStates(transition); Node<std::string> source = getSourceState(transition); - + #if 0 std::cout << "getTransitionDomain: " << std::endl << transition << std::endl; #endif - + if (tStates.size() == 0) { return Arabica::DOM::Node<std::string>(); // null } std::string transitionType = (HAS_ATTR(transition, "type") ? ATTR(transition, "type") : "external"); - + if (iequals(transitionType, "internal") && isCompound(source)) { for (int i = 0; i < tStates.size(); i++) { const Node<std::string>& s = tStates[i]; @@ -1220,7 +1247,8 @@ Arabica::DOM::Node<std::string> InterpreterRC::getTransitionDomain(const Arabica } return source; } -BREAK_LOOP:; +BREAK_LOOP: + ; Arabica::XPath::NodeSet<std::string> states; states.push_back(source); states.push_back(tStates); @@ -1247,10 +1275,10 @@ Arabica::DOM::Node<std::string> InterpreterRC::findLCCA(const Arabica::XPath::No } ancestor = ancestors[i]; break; - NEXT_ANCESTOR: +NEXT_ANCESTOR: ; } - + // take uppermost root as ancestor if (!ancestor) ancestor = _scxml; @@ -1261,22 +1289,22 @@ Arabica::DOM::Node<std::string> InterpreterRC::findLCCA(const Arabica::XPath::No /** If state2 is null, returns the set of all ancestors of state1 in ancestry order (state1's parent followed by the parent's parent, etc. up to an including the - <scxml> element). If state2 is non-null, returns inancestry order the set of all - ancestors of state1, up to but not including state2. (A "proper ancestor" of a - state is its parent, or the parent's parent, or the parent's parent's parent, - etc.)) If state2 is state1's parent, or equal to state1, or a descendant of + <scxml> element). If state2 is non-null, returns inancestry order the set of all + ancestors of state1, up to but not including state2. (A "proper ancestor" of a + state is its parent, or the parent's parent, or the parent's parent's parent, + etc.)) If state2 is state1's parent, or equal to state1, or a descendant of state1, this returns the empty set. */ Arabica::XPath::NodeSet<std::string> InterpreterRC::getProperAncestors(const Arabica::DOM::Node<std::string>& state1, const Arabica::DOM::Node<std::string>& state2) { NodeSet<std::string> ancestors; - + if (!state1 || !isState(state1)) return ancestors; if (!state2) { /** - If state2 is null, returns the set of all ancestors of state1 in ancestry - order (state1's parent followed by the parent's parent, etc. up to an + If state2 is null, returns the set of all ancestors of state1 in ancestry + order (state1's parent followed by the parent's parent, etc. up to an including the <scxml> element). */ Arabica::DOM::Node<std::string> parent = state1.getParentNode(); @@ -1287,16 +1315,16 @@ Arabica::XPath::NodeSet<std::string> InterpreterRC::getProperAncestors(const Ara return ancestors; } - /** + /** If state2 is state1's parent, or equal to state1, or a descendant of - state1, this returns the empty set + state1, this returns the empty set */ if (state1.getParentNode() == state2 || state1 == state2 || isDescendant(state2, state1)) { return ancestors; } - + /** - If state2 is non-null, returns in ancestry order the set of all ancestors + If state2 is non-null, returns in ancestry order the set of all ancestors of state1, up to but not including state2. */ Arabica::DOM::Node<std::string> parent = state1.getParentNode(); @@ -1309,7 +1337,7 @@ Arabica::XPath::NodeSet<std::string> InterpreterRC::getProperAncestors(const Ara NodeSet<std::string> InterpreterRC::getTargetStates(const Arabica::DOM::Node<std::string>& transition) { NodeSet<std::string> targetStates; - + std::string targetId = ((Arabica::DOM::Element<std::string>)transition).getAttribute("target"); std::list<std::string> targetIds = InterpreterImpl::tokenizeIdRefs(ATTR(transition, "target")); if (targetIds.size() > 0) { @@ -1332,14 +1360,14 @@ NodeSet<std::string> InterpreterRC::getTargetStates(const Arabica::DOM::Node<std Returns 'true' if state1 is a descendant of state2 (a child, or a child of a child, or a child of a child of a child, etc.) Otherwise returns 'false'. */ bool InterpreterRC::isDescendant(const Arabica::DOM::Node<std::string>& state1, const Arabica::DOM::Node<std::string>& state2) { - return false; + return false; } /** Returns a list containing all <state>, <final>, and <parallel> children of state1. */ Arabica::XPath::NodeSet<std::string> InterpreterRC::getChildStates(const Arabica::DOM::Node<std::string>& state) { - return Arabica::XPath::NodeSet<std::string>(); + return Arabica::XPath::NodeSet<std::string>(); } #endif diff --git a/src/uscxml/interpreter/InterpreterRC.h b/src/uscxml/interpreter/InterpreterRC.h index bff07b7..0a09c36 100644 --- a/src/uscxml/interpreter/InterpreterRC.h +++ b/src/uscxml/interpreter/InterpreterRC.h @@ -43,33 +43,33 @@ class InterpreterRC : public InterpreterImpl { Arabica::XPath::NodeSet<std::string> computeExitSet(const Arabica::DOM::Node<std::string>& transition); void computeEntrySet(const Arabica::XPath::NodeSet<std::string>& transitions, - Arabica::XPath::NodeSet<std::string>& statesToEnter, - Arabica::XPath::NodeSet<std::string>& statesForDefaultEntry, - std::map<std::string, Arabica::DOM::Node<std::string> > defaultHistoryContent); + Arabica::XPath::NodeSet<std::string>& statesToEnter, + Arabica::XPath::NodeSet<std::string>& statesForDefaultEntry, + std::map<std::string, Arabica::DOM::Node<std::string> > defaultHistoryContent); void computeEntrySet(const Arabica::DOM::Node<std::string>& transition, - Arabica::XPath::NodeSet<std::string>& statesToEnter, - Arabica::XPath::NodeSet<std::string>& statesForDefaultEntry, - std::map<std::string, Arabica::DOM::Node<std::string> > defaultHistoryContent); + Arabica::XPath::NodeSet<std::string>& statesToEnter, + Arabica::XPath::NodeSet<std::string>& statesForDefaultEntry, + std::map<std::string, Arabica::DOM::Node<std::string> > defaultHistoryContent); Arabica::XPath::NodeSet<std::string> removeConflictingTransitions(const Arabica::XPath::NodeSet<std::string>& enabledTransitions); Arabica::DOM::Node<std::string> getTransitionDomain(const Arabica::DOM::Node<std::string>& transition); void addDescendantStatesToEnter(const Arabica::DOM::Node<std::string>& state, - Arabica::XPath::NodeSet<std::string>& statesToEnter, - Arabica::XPath::NodeSet<std::string>& statesForDefaultEntry, - std::map<std::string, Arabica::DOM::Node<std::string> > defaultHistoryContent); + Arabica::XPath::NodeSet<std::string>& statesToEnter, + Arabica::XPath::NodeSet<std::string>& statesForDefaultEntry, + std::map<std::string, Arabica::DOM::Node<std::string> > defaultHistoryContent); void addAncestorStatesToEnter(const Arabica::DOM::Node<std::string>& state, - const Arabica::DOM::Node<std::string>& ancestor, - Arabica::XPath::NodeSet<std::string>& statesToEnter, - Arabica::XPath::NodeSet<std::string>& statesForDefaultEntry, - std::map<std::string, Arabica::DOM::Node<std::string> > defaultHistoryContent); + const Arabica::DOM::Node<std::string>& ancestor, + Arabica::XPath::NodeSet<std::string>& statesToEnter, + Arabica::XPath::NodeSet<std::string>& statesForDefaultEntry, + std::map<std::string, Arabica::DOM::Node<std::string> > defaultHistoryContent); bool isInFinalState(const Arabica::DOM::Node<std::string>& state); Arabica::DOM::Node<std::string> findLCCA(const Arabica::XPath::NodeSet<std::string>& states); Arabica::XPath::NodeSet<std::string> getProperAncestors(const Arabica::DOM::Node<std::string>& s1, - const Arabica::DOM::Node<std::string>& s2); + const Arabica::DOM::Node<std::string>& s2); Arabica::XPath::NodeSet<std::string> getTargetStates(const Arabica::DOM::Node<std::string>& transition); diff --git a/src/uscxml/plugins/datamodel/ecmascript/JavaScriptCore/JSCDOM.cpp b/src/uscxml/plugins/datamodel/ecmascript/JavaScriptCore/JSCDOM.cpp index 2a84c24..40bd464 100644 --- a/src/uscxml/plugins/datamodel/ecmascript/JavaScriptCore/JSCDOM.cpp +++ b/src/uscxml/plugins/datamodel/ecmascript/JavaScriptCore/JSCDOM.cpp @@ -23,6 +23,7 @@ namespace Arabica { namespace DOM { JSCDOM::JSCDOM() { + nsInfo = NULL; xpath = NULL; storage = NULL; } diff --git a/src/uscxml/plugins/datamodel/ecmascript/JavaScriptCore/JSCDOM.h b/src/uscxml/plugins/datamodel/ecmascript/JavaScriptCore/JSCDOM.h index 5a6bfea..cb196ff 100644 --- a/src/uscxml/plugins/datamodel/ecmascript/JavaScriptCore/JSCDOM.h +++ b/src/uscxml/plugins/datamodel/ecmascript/JavaScriptCore/JSCDOM.h @@ -49,6 +49,7 @@ public: JSCDOM(); virtual ~JSCDOM(); uscxml::Storage* storage; + uscxml::NameSpaceInfo* nsInfo; Arabica::XPath::XPath<std::string>* xpath; }; diff --git a/src/uscxml/plugins/datamodel/ecmascript/JavaScriptCore/JSCDataModel.cpp b/src/uscxml/plugins/datamodel/ecmascript/JavaScriptCore/JSCDataModel.cpp index dece4f2..2e8e6d2 100644 --- a/src/uscxml/plugins/datamodel/ecmascript/JavaScriptCore/JSCDataModel.cpp +++ b/src/uscxml/plugins/datamodel/ecmascript/JavaScriptCore/JSCDataModel.cpp @@ -125,8 +125,9 @@ boost::shared_ptr<DataModelImpl> JSCDataModel::create(InterpreterImpl* interpret dm->_dom = new JSCDOM(); dm->_dom->xpath = new XPath<std::string>(); - dm->_dom->xpath->setNamespaceContext(interpreter->getNSContext()); + dm->_dom->xpath->setNamespaceContext(*interpreter->getNameSpaceInfo().nsContext); 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); @@ -632,16 +633,16 @@ std::string JSCDataModel::andExpressions(std::list<std::string> expressions) { if (expressions.size() == 0) return ""; - + if (expressions.size() == 1) return *(expressions.begin()); - + std::ostringstream exprSS; exprSS << "("; std::string conjunction = ""; for (std::list<std::string>::const_iterator exprIter = expressions.begin(); - exprIter != expressions.end(); - exprIter++) { + exprIter != expressions.end(); + exprIter++) { exprSS << conjunction << "(" << *exprIter << ")"; conjunction = " && "; } diff --git a/src/uscxml/plugins/datamodel/ecmascript/JavaScriptCore/dom/JSCDocument.cpp b/src/uscxml/plugins/datamodel/ecmascript/JavaScriptCore/dom/JSCDocument.cpp index 1527884..795ad70 100644 --- a/src/uscxml/plugins/datamodel/ecmascript/JavaScriptCore/dom/JSCDocument.cpp +++ b/src/uscxml/plugins/datamodel/ecmascript/JavaScriptCore/dom/JSCDocument.cpp @@ -55,8 +55,8 @@ JSStaticFunction JSCDocument::staticFunctions[] = { { "createEntityReference", createEntityReferenceCallback, kJSPropertyAttributeDontDelete }, { "getElementsByTagName", getElementsByTagNameCallback, kJSPropertyAttributeDontDelete }, { "importNode", importNodeCallback, kJSPropertyAttributeDontDelete }, - { "createElementNS", createElementNSCallback, kJSPropertyAttributeDontDelete }, - { "createAttributeNS", createAttributeNSCallback, kJSPropertyAttributeDontDelete }, + { "createElementNS", createElementNSCustomCallback, kJSPropertyAttributeDontDelete }, + { "createAttributeNS", createAttributeNSCustomCallback, kJSPropertyAttributeDontDelete }, { "getElementsByTagNameNS", getElementsByTagNameNSCallback, kJSPropertyAttributeDontDelete }, { "getElementById", getElementByIdCallback, kJSPropertyAttributeDontDelete }, { "evaluate", evaluateCustomCallback, kJSPropertyAttributeDontDelete }, @@ -459,94 +459,6 @@ JSValueRef JSCDocument::importNodeCallback(JSContextRef ctx, JSObjectRef functio return JSValueMakeUndefined(ctx); } -JSValueRef JSCDocument::createElementNSCallback(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObj, size_t argumentCount, const JSValueRef* arguments, JSValueRef* exception) { - - struct JSCDocumentPrivate* privData = (struct JSCDocumentPrivate*)JSObjectGetPrivate(thisObj); - - if (false) { - } else if (argumentCount == 2 && - JSValueIsString(ctx, arguments[0]) && - JSValueIsString(ctx, arguments[1])) { - JSStringRef stringReflocalNamespaceURI = JSValueToStringCopy(ctx, arguments[0], exception); - size_t localNamespaceURIMaxSize = JSStringGetMaximumUTF8CStringSize(stringReflocalNamespaceURI); - char* localNamespaceURIBuffer = new char[localNamespaceURIMaxSize]; - JSStringGetUTF8CString(stringReflocalNamespaceURI, localNamespaceURIBuffer, localNamespaceURIMaxSize); - std::string localNamespaceURI(localNamespaceURIBuffer); - JSStringRelease(stringReflocalNamespaceURI); - free(localNamespaceURIBuffer); - - JSStringRef stringReflocalQualifiedName = JSValueToStringCopy(ctx, arguments[1], exception); - size_t localQualifiedNameMaxSize = JSStringGetMaximumUTF8CStringSize(stringReflocalQualifiedName); - char* localQualifiedNameBuffer = new char[localQualifiedNameMaxSize]; - JSStringGetUTF8CString(stringReflocalQualifiedName, localQualifiedNameBuffer, localQualifiedNameMaxSize); - std::string localQualifiedName(localQualifiedNameBuffer); - JSStringRelease(stringReflocalQualifiedName); - free(localQualifiedNameBuffer); - - - Arabica::DOM::Element<std::string>* retVal = new Arabica::DOM::Element<std::string>(privData->nativeObj->createElementNS(localNamespaceURI, localQualifiedName)); - JSClassRef retClass = JSCElement::getTmpl(); - - struct JSCElement::JSCElementPrivate* retPrivData = new JSCElement::JSCElementPrivate(); - retPrivData->dom = privData->dom; - retPrivData->nativeObj = retVal; - - JSObjectRef retObj = JSObjectMake(ctx, retClass, retPrivData); - - return retObj; - - } - - JSStringRef exceptionString = JSStringCreateWithUTF8CString("Parameter mismatch while calling createElementNS"); - *exception = JSValueMakeString(ctx, exceptionString); - JSStringRelease(exceptionString); - return JSValueMakeUndefined(ctx); -} - -JSValueRef JSCDocument::createAttributeNSCallback(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObj, size_t argumentCount, const JSValueRef* arguments, JSValueRef* exception) { - - struct JSCDocumentPrivate* privData = (struct JSCDocumentPrivate*)JSObjectGetPrivate(thisObj); - - if (false) { - } else if (argumentCount == 2 && - JSValueIsString(ctx, arguments[0]) && - JSValueIsString(ctx, arguments[1])) { - JSStringRef stringReflocalNamespaceURI = JSValueToStringCopy(ctx, arguments[0], exception); - size_t localNamespaceURIMaxSize = JSStringGetMaximumUTF8CStringSize(stringReflocalNamespaceURI); - char* localNamespaceURIBuffer = new char[localNamespaceURIMaxSize]; - JSStringGetUTF8CString(stringReflocalNamespaceURI, localNamespaceURIBuffer, localNamespaceURIMaxSize); - std::string localNamespaceURI(localNamespaceURIBuffer); - JSStringRelease(stringReflocalNamespaceURI); - free(localNamespaceURIBuffer); - - JSStringRef stringReflocalQualifiedName = JSValueToStringCopy(ctx, arguments[1], exception); - size_t localQualifiedNameMaxSize = JSStringGetMaximumUTF8CStringSize(stringReflocalQualifiedName); - char* localQualifiedNameBuffer = new char[localQualifiedNameMaxSize]; - JSStringGetUTF8CString(stringReflocalQualifiedName, localQualifiedNameBuffer, localQualifiedNameMaxSize); - std::string localQualifiedName(localQualifiedNameBuffer); - JSStringRelease(stringReflocalQualifiedName); - free(localQualifiedNameBuffer); - - - Arabica::DOM::Attr<std::string>* retVal = new Arabica::DOM::Attr<std::string>(privData->nativeObj->createAttributeNS(localNamespaceURI, localQualifiedName)); - JSClassRef retClass = JSCAttr::getTmpl(); - - struct JSCAttr::JSCAttrPrivate* retPrivData = new JSCAttr::JSCAttrPrivate(); - retPrivData->dom = privData->dom; - retPrivData->nativeObj = retVal; - - JSObjectRef retObj = JSObjectMake(ctx, retClass, retPrivData); - - return retObj; - - } - - JSStringRef exceptionString = JSStringCreateWithUTF8CString("Parameter mismatch while calling createAttributeNS"); - *exception = JSValueMakeString(ctx, exceptionString); - JSStringRelease(exceptionString); - return JSValueMakeUndefined(ctx); -} - JSValueRef JSCDocument::getElementsByTagNameNSCallback(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObj, size_t argumentCount, const JSValueRef* arguments, JSValueRef* exception) { struct JSCDocumentPrivate* privData = (struct JSCDocumentPrivate*)JSObjectGetPrivate(thisObj); diff --git a/src/uscxml/plugins/datamodel/ecmascript/JavaScriptCore/dom/JSCDocument.h b/src/uscxml/plugins/datamodel/ecmascript/JavaScriptCore/dom/JSCDocument.h index f6b167e..1b300fb 100644 --- a/src/uscxml/plugins/datamodel/ecmascript/JavaScriptCore/dom/JSCDocument.h +++ b/src/uscxml/plugins/datamodel/ecmascript/JavaScriptCore/dom/JSCDocument.h @@ -48,8 +48,8 @@ public: static JSValueRef createEntityReferenceCallback(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObj, size_t argumentCount, const JSValueRef* arguments, JSValueRef* exception); static JSValueRef getElementsByTagNameCallback(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObj, size_t argumentCount, const JSValueRef* arguments, JSValueRef* exception); static JSValueRef importNodeCallback(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObj, size_t argumentCount, const JSValueRef* arguments, JSValueRef* exception); - static JSValueRef createElementNSCallback(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObj, size_t argumentCount, const JSValueRef* arguments, JSValueRef* exception); - static JSValueRef createAttributeNSCallback(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObj, size_t argumentCount, const JSValueRef* arguments, JSValueRef* exception); + static JSValueRef createElementNSCustomCallback(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObj, size_t argumentCount, const JSValueRef* arguments, JSValueRef* exception); + static JSValueRef createAttributeNSCustomCallback(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObj, size_t argumentCount, const JSValueRef* arguments, JSValueRef* exception); static JSValueRef getElementsByTagNameNSCallback(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObj, size_t argumentCount, const JSValueRef* arguments, JSValueRef* exception); static JSValueRef getElementByIdCallback(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObj, size_t argumentCount, const JSValueRef* arguments, JSValueRef* exception); static JSValueRef evaluateCustomCallback(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObj, size_t argumentCount, const JSValueRef* arguments, JSValueRef* exception); diff --git a/src/uscxml/plugins/datamodel/ecmascript/JavaScriptCore/dom/JSCDocumentCustom.cpp b/src/uscxml/plugins/datamodel/ecmascript/JavaScriptCore/dom/JSCDocumentCustom.cpp index 6f15c72..c6ee022 100644 --- a/src/uscxml/plugins/datamodel/ecmascript/JavaScriptCore/dom/JSCDocumentCustom.cpp +++ b/src/uscxml/plugins/datamodel/ecmascript/JavaScriptCore/dom/JSCDocumentCustom.cpp @@ -18,6 +18,8 @@ */ #include "JSCDocument.h" +#include "JSCElement.h" +#include "JSCAttr.h" #include "JSCStorage.h" #include "JSCXPathResult.h" #include "JSCNode.h" @@ -141,5 +143,99 @@ JSValueRef JSCDocument::evaluateCustomCallback(JSContextRef ctx, JSObjectRef fun #endif } +JSValueRef JSCDocument::createElementNSCustomCallback(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObj, size_t argumentCount, const JSValueRef* arguments, JSValueRef* exception) { + + struct JSCDocumentPrivate* privData = (struct JSCDocumentPrivate*)JSObjectGetPrivate(thisObj); + + if (false) { + } else if (argumentCount == 2 && + JSValueIsString(ctx, arguments[0]) && + JSValueIsString(ctx, arguments[1])) { + JSStringRef stringReflocalNamespaceURI = JSValueToStringCopy(ctx, arguments[0], exception); + size_t localNamespaceURIMaxSize = JSStringGetMaximumUTF8CStringSize(stringReflocalNamespaceURI); + char* localNamespaceURIBuffer = new char[localNamespaceURIMaxSize]; + JSStringGetUTF8CString(stringReflocalNamespaceURI, localNamespaceURIBuffer, localNamespaceURIMaxSize); + std::string localNamespaceURI(localNamespaceURIBuffer); + JSStringRelease(stringReflocalNamespaceURI); + free(localNamespaceURIBuffer); + + JSStringRef stringReflocalQualifiedName = JSValueToStringCopy(ctx, arguments[1], exception); + size_t localQualifiedNameMaxSize = JSStringGetMaximumUTF8CStringSize(stringReflocalQualifiedName); + char* localQualifiedNameBuffer = new char[localQualifiedNameMaxSize]; + JSStringGetUTF8CString(stringReflocalQualifiedName, localQualifiedNameBuffer, localQualifiedNameMaxSize); + std::string localQualifiedName(localQualifiedNameBuffer); + JSStringRelease(stringReflocalQualifiedName); + free(localQualifiedNameBuffer); + + + Arabica::DOM::Element<std::string>* retVal = new Arabica::DOM::Element<std::string>(privData->nativeObj->createElementNS(localNamespaceURI, localQualifiedName)); + if (privData->dom->nsInfo->nsToPrefix.find(localNamespaceURI) != privData->dom->nsInfo->nsToPrefix.end()) + retVal->setPrefix(privData->dom->nsInfo->nsToPrefix[localNamespaceURI]); + + JSClassRef retClass = JSCElement::getTmpl(); + + struct JSCElement::JSCElementPrivate* retPrivData = new JSCElement::JSCElementPrivate(); + retPrivData->dom = privData->dom; + retPrivData->nativeObj = retVal; + + JSObjectRef retObj = JSObjectMake(ctx, retClass, retPrivData); + + return retObj; + + } + + JSStringRef exceptionString = JSStringCreateWithUTF8CString("Parameter mismatch while calling createElementNS"); + *exception = JSValueMakeString(ctx, exceptionString); + JSStringRelease(exceptionString); + return JSValueMakeUndefined(ctx); +} + +JSValueRef JSCDocument::createAttributeNSCustomCallback(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObj, size_t argumentCount, const JSValueRef* arguments, JSValueRef* exception) { + + struct JSCDocumentPrivate* privData = (struct JSCDocumentPrivate*)JSObjectGetPrivate(thisObj); + + if (false) { + } else if (argumentCount == 2 && + JSValueIsString(ctx, arguments[0]) && + JSValueIsString(ctx, arguments[1])) { + JSStringRef stringReflocalNamespaceURI = JSValueToStringCopy(ctx, arguments[0], exception); + size_t localNamespaceURIMaxSize = JSStringGetMaximumUTF8CStringSize(stringReflocalNamespaceURI); + char* localNamespaceURIBuffer = new char[localNamespaceURIMaxSize]; + JSStringGetUTF8CString(stringReflocalNamespaceURI, localNamespaceURIBuffer, localNamespaceURIMaxSize); + std::string localNamespaceURI(localNamespaceURIBuffer); + JSStringRelease(stringReflocalNamespaceURI); + free(localNamespaceURIBuffer); + + JSStringRef stringReflocalQualifiedName = JSValueToStringCopy(ctx, arguments[1], exception); + size_t localQualifiedNameMaxSize = JSStringGetMaximumUTF8CStringSize(stringReflocalQualifiedName); + char* localQualifiedNameBuffer = new char[localQualifiedNameMaxSize]; + JSStringGetUTF8CString(stringReflocalQualifiedName, localQualifiedNameBuffer, localQualifiedNameMaxSize); + std::string localQualifiedName(localQualifiedNameBuffer); + JSStringRelease(stringReflocalQualifiedName); + free(localQualifiedNameBuffer); + + + Arabica::DOM::Attr<std::string>* retVal = new Arabica::DOM::Attr<std::string>(privData->nativeObj->createAttributeNS(localNamespaceURI, localQualifiedName)); + if (privData->dom->nsInfo->nsToPrefix.find(localNamespaceURI) != privData->dom->nsInfo->nsToPrefix.end()) + retVal->setPrefix(privData->dom->nsInfo->nsToPrefix[localNamespaceURI]); + + JSClassRef retClass = JSCAttr::getTmpl(); + + struct JSCAttr::JSCAttrPrivate* retPrivData = new JSCAttr::JSCAttrPrivate(); + retPrivData->dom = privData->dom; + retPrivData->nativeObj = retVal; + + JSObjectRef retObj = JSObjectMake(ctx, retClass, retPrivData); + + return retObj; + + } + + JSStringRef exceptionString = JSStringCreateWithUTF8CString("Parameter mismatch while calling createAttributeNS"); + *exception = JSValueMakeString(ctx, exceptionString); + JSStringRelease(exceptionString); + return JSValueMakeUndefined(ctx); +} + } }
\ No newline at end of file diff --git a/src/uscxml/plugins/datamodel/ecmascript/v8/V8DOM.cpp b/src/uscxml/plugins/datamodel/ecmascript/v8/V8DOM.cpp index b09d670..87e7966 100644 --- a/src/uscxml/plugins/datamodel/ecmascript/v8/V8DOM.cpp +++ b/src/uscxml/plugins/datamodel/ecmascript/v8/V8DOM.cpp @@ -23,9 +23,14 @@ namespace Arabica { namespace DOM { V8DOM::V8DOM() { + nsInfo = NULL; + xpath = NULL; + storage = NULL; } V8DOM::~V8DOM() { + if (nsInfo) + delete(nsInfo); if (xpath) delete(xpath); if (storage) diff --git a/src/uscxml/plugins/datamodel/ecmascript/v8/V8DOM.h b/src/uscxml/plugins/datamodel/ecmascript/v8/V8DOM.h index a10b980..dd0c18a 100644 --- a/src/uscxml/plugins/datamodel/ecmascript/v8/V8DOM.h +++ b/src/uscxml/plugins/datamodel/ecmascript/v8/V8DOM.h @@ -70,6 +70,7 @@ public: // return v8::External::New(pointer); } + uscxml::NameSpaceInfo* nsInfo; Arabica::XPath::XPath<std::string>* xpath; uscxml::Storage* storage; }; diff --git a/src/uscxml/plugins/datamodel/ecmascript/v8/V8DataModel.cpp b/src/uscxml/plugins/datamodel/ecmascript/v8/V8DataModel.cpp index 1341d09..b18e039 100644 --- a/src/uscxml/plugins/datamodel/ecmascript/v8/V8DataModel.cpp +++ b/src/uscxml/plugins/datamodel/ecmascript/v8/V8DataModel.cpp @@ -94,9 +94,9 @@ boost::shared_ptr<DataModelImpl> V8DataModel::create(InterpreterImpl* interprete dm->_dom = new V8DOM(); // dom->interpreter = interpreter; dm->_dom->xpath = new XPath<std::string>(); - dm->_dom->xpath->setNamespaceContext(interpreter->getNSContext()); + dm->_dom->xpath->setNamespaceContext(*interpreter->getNameSpaceInfo().nsContext); dm->_dom->storage = new Storage(URL::getResourceDir() + PATH_SEPERATOR + interpreter->getName() + ".storage"); - + dm->_dom->nsInfo = new NameSpaceInfo(interpreter->getNameSpaceInfo()); // see http://stackoverflow.com/questions/3171418/v8-functiontemplate-class-instance // some free functions @@ -661,7 +661,7 @@ void V8DataModel::init(const std::string& location, std::string V8DataModel::andExpressions(std::list<std::string> expressions) { if (expressions.size() == 0) return ""; - + if (expressions.size() == 1) return *(expressions.begin()); @@ -669,8 +669,8 @@ std::string V8DataModel::andExpressions(std::list<std::string> expressions) { exprSS << "("; std::string conjunction = ""; for (std::list<std::string>::const_iterator exprIter = expressions.begin(); - exprIter != expressions.end(); - exprIter++) { + exprIter != expressions.end(); + exprIter++) { exprSS << conjunction << "(" << *exprIter << ")"; conjunction = " && "; } diff --git a/src/uscxml/plugins/datamodel/ecmascript/v8/dom/V8Document.cpp b/src/uscxml/plugins/datamodel/ecmascript/v8/dom/V8Document.cpp index 1e4a2dc..226cd26 100644 --- a/src/uscxml/plugins/datamodel/ecmascript/v8/dom/V8Document.cpp +++ b/src/uscxml/plugins/datamodel/ecmascript/v8/dom/V8Document.cpp @@ -368,64 +368,6 @@ v8::Handle<v8::Value> V8Document::importNodeCallback(const v8::Arguments& args) return v8::Undefined(); } -v8::Handle<v8::Value> V8Document::createElementNSCallback(const v8::Arguments& args) { - - v8::Local<v8::Object> self = args.Holder(); - struct V8DocumentPrivate* privData = V8DOM::toClassPtr<V8DocumentPrivate >(self->GetInternalField(0)); - if (false) { - } else if (args.Length() == 2 && - args[0]->IsString() && - args[1]->IsString()) { - v8::String::AsciiValue localNamespaceURI(args[0]); - v8::String::AsciiValue localQualifiedName(args[1]); - - Arabica::DOM::Element<std::string>* retVal = new Arabica::DOM::Element<std::string>(privData->nativeObj->createElementNS(*localNamespaceURI, *localQualifiedName)); - v8::Handle<v8::Function> retCtor = V8Element::getTmpl()->GetFunction(); - v8::Persistent<v8::Object> retObj = v8::Persistent<v8::Object>::New(retCtor->NewInstance()); - - struct V8Element::V8ElementPrivate* retPrivData = new V8Element::V8ElementPrivate(); - retPrivData->dom = privData->dom; - retPrivData->nativeObj = retVal; - - retObj->SetInternalField(0, V8DOM::toExternal(retPrivData)); - - retObj.MakeWeak(0, V8Element::jsDestructor); - return retObj; - - } - throw V8Exception("Parameter mismatch while calling createElementNS"); - return v8::Undefined(); -} - -v8::Handle<v8::Value> V8Document::createAttributeNSCallback(const v8::Arguments& args) { - - v8::Local<v8::Object> self = args.Holder(); - struct V8DocumentPrivate* privData = V8DOM::toClassPtr<V8DocumentPrivate >(self->GetInternalField(0)); - if (false) { - } else if (args.Length() == 2 && - args[0]->IsString() && - args[1]->IsString()) { - v8::String::AsciiValue localNamespaceURI(args[0]); - v8::String::AsciiValue localQualifiedName(args[1]); - - Arabica::DOM::Attr<std::string>* retVal = new Arabica::DOM::Attr<std::string>(privData->nativeObj->createAttributeNS(*localNamespaceURI, *localQualifiedName)); - v8::Handle<v8::Function> retCtor = V8Attr::getTmpl()->GetFunction(); - v8::Persistent<v8::Object> retObj = v8::Persistent<v8::Object>::New(retCtor->NewInstance()); - - struct V8Attr::V8AttrPrivate* retPrivData = new V8Attr::V8AttrPrivate(); - retPrivData->dom = privData->dom; - retPrivData->nativeObj = retVal; - - retObj->SetInternalField(0, V8DOM::toExternal(retPrivData)); - - retObj.MakeWeak(0, V8Attr::jsDestructor); - return retObj; - - } - throw V8Exception("Parameter mismatch while calling createAttributeNS"); - return v8::Undefined(); -} - v8::Handle<v8::Value> V8Document::getElementsByTagNameNSCallback(const v8::Arguments& args) { v8::Local<v8::Object> self = args.Holder(); diff --git a/src/uscxml/plugins/datamodel/ecmascript/v8/dom/V8Document.h b/src/uscxml/plugins/datamodel/ecmascript/v8/dom/V8Document.h index cebc5d1..373d18a 100644 --- a/src/uscxml/plugins/datamodel/ecmascript/v8/dom/V8Document.h +++ b/src/uscxml/plugins/datamodel/ecmascript/v8/dom/V8Document.h @@ -51,8 +51,8 @@ public: static v8::Handle<v8::Value> createEntityReferenceCallback(const v8::Arguments&); static v8::Handle<v8::Value> getElementsByTagNameCallback(const v8::Arguments&); static v8::Handle<v8::Value> importNodeCallback(const v8::Arguments&); - static v8::Handle<v8::Value> createElementNSCallback(const v8::Arguments&); - static v8::Handle<v8::Value> createAttributeNSCallback(const v8::Arguments&); + static v8::Handle<v8::Value> createElementNSCustomCallback(const v8::Arguments&); + static v8::Handle<v8::Value> createAttributeNSCustomCallback(const v8::Arguments&); static v8::Handle<v8::Value> getElementsByTagNameNSCallback(const v8::Arguments&); static v8::Handle<v8::Value> getElementByIdCallback(const v8::Arguments&); static v8::Handle<v8::Value> evaluateCustomCallback(const v8::Arguments&); @@ -105,9 +105,9 @@ public: prototype->Set(v8::String::NewSymbol("importNode"), v8::FunctionTemplate::New(V8Document::importNodeCallback, v8::Undefined()), static_cast<v8::PropertyAttribute>(v8::DontDelete)); prototype->Set(v8::String::NewSymbol("createElementNS"), - v8::FunctionTemplate::New(V8Document::createElementNSCallback, v8::Undefined()), static_cast<v8::PropertyAttribute>(v8::DontDelete)); + v8::FunctionTemplate::New(V8Document::createElementNSCustomCallback, v8::Undefined()), static_cast<v8::PropertyAttribute>(v8::DontDelete)); prototype->Set(v8::String::NewSymbol("createAttributeNS"), - v8::FunctionTemplate::New(V8Document::createAttributeNSCallback, v8::Undefined()), static_cast<v8::PropertyAttribute>(v8::DontDelete)); + v8::FunctionTemplate::New(V8Document::createAttributeNSCustomCallback, v8::Undefined()), static_cast<v8::PropertyAttribute>(v8::DontDelete)); prototype->Set(v8::String::NewSymbol("getElementsByTagNameNS"), v8::FunctionTemplate::New(V8Document::getElementsByTagNameNSCallback, v8::Undefined()), static_cast<v8::PropertyAttribute>(v8::DontDelete)); prototype->Set(v8::String::NewSymbol("getElementById"), diff --git a/src/uscxml/plugins/datamodel/ecmascript/v8/dom/V8DocumentCustom.cpp b/src/uscxml/plugins/datamodel/ecmascript/v8/dom/V8DocumentCustom.cpp index 2e4d7c4..8659ccd 100644 --- a/src/uscxml/plugins/datamodel/ecmascript/v8/dom/V8DocumentCustom.cpp +++ b/src/uscxml/plugins/datamodel/ecmascript/v8/dom/V8DocumentCustom.cpp @@ -20,6 +20,8 @@ #include "V8Document.h" #include "V8XPathResult.h" #include "V8Storage.h" +#include "V8Attr.h" +#include "V8Element.h" namespace Arabica { namespace DOM { @@ -81,5 +83,69 @@ v8::Handle<v8::Value> V8Document::evaluateCustomCallback(const v8::Arguments& ar } +v8::Handle<v8::Value> V8Document::createElementNSCustomCallback(const v8::Arguments& args) { + + v8::Local<v8::Object> self = args.Holder(); + struct V8DocumentPrivate* privData = V8DOM::toClassPtr<V8DocumentPrivate >(self->GetInternalField(0)); + if (false) { + } else if (args.Length() == 2 && + args[0]->IsString() && + args[1]->IsString()) { + v8::String::AsciiValue localNamespaceURI(args[0]); + v8::String::AsciiValue localQualifiedName(args[1]); + + Arabica::DOM::Element<std::string>* retVal = new Arabica::DOM::Element<std::string>(privData->nativeObj->createElementNS(*localNamespaceURI, *localQualifiedName)); + if (privData->dom->nsInfo->nsToPrefix.find(*localNamespaceURI) != privData->dom->nsInfo->nsToPrefix.end()) + retVal->setPrefix(privData->dom->nsInfo->nsToPrefix[*localNamespaceURI]); + + v8::Handle<v8::Function> retCtor = V8Element::getTmpl()->GetFunction(); + v8::Persistent<v8::Object> retObj = v8::Persistent<v8::Object>::New(retCtor->NewInstance()); + + struct V8Element::V8ElementPrivate* retPrivData = new V8Element::V8ElementPrivate(); + retPrivData->dom = privData->dom; + retPrivData->nativeObj = retVal; + + retObj->SetInternalField(0, V8DOM::toExternal(retPrivData)); + + retObj.MakeWeak(0, V8Element::jsDestructor); + return retObj; + + } + throw V8Exception("Parameter mismatch while calling createElementNS"); + return v8::Undefined(); +} + +v8::Handle<v8::Value> V8Document::createAttributeNSCustomCallback(const v8::Arguments& args) { + + v8::Local<v8::Object> self = args.Holder(); + struct V8DocumentPrivate* privData = V8DOM::toClassPtr<V8DocumentPrivate >(self->GetInternalField(0)); + if (false) { + } else if (args.Length() == 2 && + args[0]->IsString() && + args[1]->IsString()) { + v8::String::AsciiValue localNamespaceURI(args[0]); + v8::String::AsciiValue localQualifiedName(args[1]); + + Arabica::DOM::Attr<std::string>* retVal = new Arabica::DOM::Attr<std::string>(privData->nativeObj->createAttributeNS(*localNamespaceURI, *localQualifiedName)); + if (privData->dom->nsInfo->nsToPrefix.find(*localNamespaceURI) != privData->dom->nsInfo->nsToPrefix.end()) + retVal->setPrefix(privData->dom->nsInfo->nsToPrefix[*localNamespaceURI]); + + v8::Handle<v8::Function> retCtor = V8Attr::getTmpl()->GetFunction(); + v8::Persistent<v8::Object> retObj = v8::Persistent<v8::Object>::New(retCtor->NewInstance()); + + struct V8Attr::V8AttrPrivate* retPrivData = new V8Attr::V8AttrPrivate(); + retPrivData->dom = privData->dom; + retPrivData->nativeObj = retVal; + + retObj->SetInternalField(0, V8DOM::toExternal(retPrivData)); + + retObj.MakeWeak(0, V8Attr::jsDestructor); + return retObj; + + } + throw V8Exception("Parameter mismatch while calling createAttributeNS"); + return v8::Undefined(); +} + } }
\ No newline at end of file diff --git a/src/uscxml/plugins/datamodel/prolog/swi/SWIDataModel.cpp b/src/uscxml/plugins/datamodel/prolog/swi/SWIDataModel.cpp index 133925e..0ad6030 100644 --- a/src/uscxml/plugins/datamodel/prolog/swi/SWIDataModel.cpp +++ b/src/uscxml/plugins/datamodel/prolog/swi/SWIDataModel.cpp @@ -42,10 +42,10 @@ catch (PlException plex) { \ e.data.compound["cause"] = (char*)plex; \ throw e; \ } \ - + #define PL_MODULE \ _interpreter.getSessionId().c_str() \ - + #define SET_PL_ENGINE(dm) \ assert(_swiEngines.find(dm) != _swiEngines.end()); \ int rc = PL_set_engine(_swiEngines[dm], NULL); \ @@ -197,7 +197,7 @@ foreign_t SWIDataModel::inPredicate(term_t a0, int arity, void* context) { char *s; if ( PL_get_atom_chars(a0, &s) ) { if (_dmPtr->_interpreter->isInState(s)) { - return true; + return true; } } return FALSE; @@ -233,7 +233,7 @@ void SWIDataModel::initialize() { void SWIDataModel::setEvent(const Event& event) { SWIEngineLock engineLock; - + // remove old event try { PlCall("retractall(event(_))"); @@ -331,7 +331,7 @@ void SWIDataModel::setEvent(const Event& event) { void SWIDataModel::assertFromData(const Data& data, const std::string& expr, size_t nesting) { if (data.atom.size() > 0) { // terminal branch, this is where we assert - + std::stringstream ss; ss << expr; // nesting++; @@ -345,7 +345,7 @@ void SWIDataModel::assertFromData(const Data& data, const std::string& expr, siz for (size_t i = 0; i < nesting; i++) { ss << ")"; } - + // std::cout << ss.str() << std::endl; PlCall("assert", PlCompound(ss.str().c_str())); return; @@ -402,20 +402,20 @@ void SWIDataModel::assertFromData(const Data& data, const std::string& expr, siz } #if 0 - std::list<PlCompound> SWIDataModel::getSolutions(PlCompound compound) { - std::list<PlCompound> solutions; - - PlTermv termv(compound.arity()); - for (int i = 0; i < compound.arity(); i++) { - termv[i] = compound[i + 1]; - } - PlQuery query(compound.name(), termv); - while(query.next_solution()) { +std::list<PlCompound> SWIDataModel::getSolutions(PlCompound compound) { + std::list<PlCompound> solutions; + + PlTermv termv(compound.arity()); + for (int i = 0; i < compound.arity(); i++) { + termv[i] = compound[i + 1]; + } + PlQuery query(compound.name(), termv); + while(query.next_solution()) { // std::cout << (char*)compound << std::endl; - solutions.push_back(compound); - } - return solutions; + solutions.push_back(compound); } + return solutions; +} #endif Data SWIDataModel::getStringAsData(const std::string& content) { @@ -424,17 +424,17 @@ Data SWIDataModel::getStringAsData(const std::string& content) { PlCompound compound(content.c_str()); PlCompound orig(content.c_str()); Data data; - + PlTermv termv(compound.arity()); for (int i = 0; i < compound.arity(); i++) { termv[i] = compound[i + 1]; } PlQuery query(compound.name(), termv); - + while(query.next_solution()) { std::map<std::string, PlTerm> vars = resolveAtoms(compound, orig); std::map<std::string, PlTerm>::const_iterator varIter = vars.begin(); - + while(varIter != vars.end()) { data.merge(termAsData(varIter->second)); varIter++; @@ -455,7 +455,7 @@ Data SWIDataModel::getStringAsData(const std::string& content) { } Data SWIDataModel::termAsData(PlTerm term) { - + Data data; // std::cout << term.name() << (char*)term << std::endl; @@ -692,13 +692,13 @@ bool SWIDataModel::evalAsBool(const Arabica::DOM::Node<std::string>& node, const return false; } } - + std::string SWIDataModel::evalAsString(const std::string& expr) { SWIEngineLock engineLock; try { PlCompound compound(expr.c_str()); - + if (strlen(compound.name())) { PlCompound orig(expr.c_str()); @@ -741,32 +741,32 @@ std::string SWIDataModel::evalAsString(const std::string& expr) { } } - + // this is similar to http://etalis.googlecode.com/svn/eEtalis/src/term.c std::map<std::string, PlTerm> SWIDataModel::resolveAtoms(PlTerm& term, PlTerm& orig) { try { std::map<std::string, PlTerm> atoms; switch (orig.type()) { - case PL_VARIABLE: { - atoms[(char *)orig] = term; - break; + case PL_VARIABLE: { + atoms[(char *)orig] = term; + break; + } + case PL_ATOM: + break; + case PL_STRING: + break; + case PL_INTEGER: + break; + case PL_TERM: + for (int i = 1; i <= orig.arity(); i++) { + PlTerm newTerm = term[i]; + PlTerm newOrig = orig[i]; + std::map<std::string, PlTerm> result = resolveAtoms(newTerm, newOrig); + atoms.insert(result.begin(), result.end()); } - case PL_ATOM: - break; - case PL_STRING: - break; - case PL_INTEGER: - break; - case PL_TERM: - for (int i = 1; i <= orig.arity(); i++) { - PlTerm newTerm = term[i]; - PlTerm newOrig = orig[i]; - std::map<std::string, PlTerm> result = resolveAtoms(newTerm, newOrig); - atoms.insert(result.begin(), result.end()); - } - break; - default: - LOG(ERROR) << "Resolving variable of unknown type in query solution"; + break; + default: + LOG(ERROR) << "Resolving variable of unknown type in query solution"; } return atoms; } diff --git a/src/uscxml/plugins/datamodel/prolog/swi/SWIDataModel.h b/src/uscxml/plugins/datamodel/prolog/swi/SWIDataModel.h index d52dd24..0e17f4b 100644 --- a/src/uscxml/plugins/datamodel/prolog/swi/SWIDataModel.h +++ b/src/uscxml/plugins/datamodel/prolog/swi/SWIDataModel.h @@ -49,7 +49,7 @@ public: } bool isLocked; }; - + SWIDataModel(); virtual ~SWIDataModel(); virtual boost::shared_ptr<DataModelImpl> create(InterpreterImpl* interpreter); @@ -94,7 +94,7 @@ public: virtual bool isDeclared(const std::string& expr); virtual Data getStringAsData(const std::string& content); - + virtual std::string evalAsString(const std::string& expr); virtual bool evalAsBool(const Arabica::DOM::Node<std::string>& node, const std::string& expr); virtual bool evalAsBool(const std::string& expr); @@ -108,7 +108,7 @@ protected: // virtual std::list<PlCompound> getSolutions(PlCompound compound); virtual std::map<std::string, PlTerm> resolveAtoms(PlTerm& term, PlTerm& orig); - + static int dictCallBack(term_t key, term_t value, int last, void *closure); static PL_blob_t blobType; diff --git a/src/uscxml/plugins/datamodel/promela/PromelaDataModel.cpp b/src/uscxml/plugins/datamodel/promela/PromelaDataModel.cpp index a7d7755..aa32806 100644 --- a/src/uscxml/plugins/datamodel/promela/PromelaDataModel.cpp +++ b/src/uscxml/plugins/datamodel/promela/PromelaDataModel.cpp @@ -61,16 +61,13 @@ boost::shared_ptr<DataModelImpl> PromelaDataModel::create(InterpreterImpl* inter } void PromelaDataModel::registerIOProcessor(const std::string& name, const IOProcessor& ioprocessor) { -// std::cout << "PromelaDataModel::registerIOProcessor" << std::endl; } void PromelaDataModel::setSessionId(const std::string& sessionId) { -// std::cout << "PromelaDataModel::setSessionId" << std::endl; _sessionId = sessionId; } void PromelaDataModel::setName(const std::string& name) { -// std::cout << "PromelaDataModel::setName" << std::endl; _name = name; } @@ -102,13 +99,35 @@ bool PromelaDataModel::validate(const std::string& location, const std::string& } uint32_t PromelaDataModel::getLength(const std::string& expr) { - return 0; + if (!isDeclared(expr)) { + throwErrorExecution("Variable " + expr + " was not declared"); + } + + if (!_variables[expr].hasKey("size")) { + throwErrorExecution("Variable " + expr + " is no array"); + } + + return strTo<int>(_variables[expr]["size"].atom); } void PromelaDataModel::setForeach(const std::string& item, - const std::string& array, - const std::string& index, - uint32_t iteration) { + const std::string& array, + const std::string& index, + uint32_t iteration) { + // assign array element to item + std::stringstream ss; + ss << array << "[" << iteration << "]"; + + PromelaParser itemParser(item, PromelaParser::PROMELA_EXPR); + PromelaParser arrayParser(ss.str(), PromelaParser::PROMELA_EXPR); + + setVariable(itemParser.ast, getVariable(arrayParser.ast)); + + if (index.length() > 0) { + PromelaParser indexParser(index, PromelaParser::PROMELA_EXPR); + setVariable(indexParser.ast, iteration); + } + } void PromelaDataModel::eval(const Element<std::string>& scriptElem, const std::string& expr) { @@ -126,7 +145,7 @@ bool PromelaDataModel::evalAsBool(const Arabica::DOM::Node<std::string>& node, c // parser.dump(); return evaluateExpr(parser.ast) > 0; } - + std::string PromelaDataModel::evalAsString(const std::string& expr) { if (isDeclared(expr)) { return Data::toJSON(_variables[expr]); @@ -135,8 +154,8 @@ std::string PromelaDataModel::evalAsString(const std::string& expr) { } void PromelaDataModel::assign(const Element<std::string>& assignElem, - const Node<std::string>& node, - const std::string& content) { + const Node<std::string>& node, + const std::string& content) { PromelaParser parser(content, PromelaParser::PROMELA_DECL); evaluateDecl(parser.ast); // parser.dump(); @@ -151,10 +170,10 @@ void PromelaDataModel::evaluateDecl(void* ast) { PromelaParserNode* vis = *opIter++; PromelaParserNode* type = *opIter++; PromelaParserNode* varlist = *opIter++; - + for (std::list<PromelaParserNode*>::iterator nameIter = varlist->operands.begin(); - nameIter != varlist->operands.end(); - nameIter++) { + nameIter != varlist->operands.end(); + nameIter++) { Data variable; variable.compound["vis"] = Data(vis->value, Data::VERBATIM); variable.compound["type"] = Data(type->value, Data::VERBATIM); @@ -162,7 +181,7 @@ void PromelaDataModel::evaluateDecl(void* ast) { if (false) { } else if ((*nameIter)->type == NAME) { // plain variables without initial assignment - + if (type->value == "mtype") { variable.compound["value"] = Data(_lastMType++, Data::INTERPRETED); } else { @@ -172,7 +191,7 @@ void PromelaDataModel::evaluateDecl(void* ast) { } else if ((*nameIter)->type == ASGN) { // initially assigned variables - + std::list<PromelaParserNode*>::iterator opIterAsgn = (*nameIter)->operands.begin(); PromelaParserNode* name = *opIterAsgn++; PromelaParserNode* expr = *opIterAsgn++; @@ -183,16 +202,16 @@ void PromelaDataModel::evaluateDecl(void* ast) { _variables.compound[name->value] = variable; } else if ((*nameIter)->type == VAR_ARRAY) { // variable arrays - + std::list<PromelaParserNode*>::iterator opIterAsgn = (*nameIter)->operands.begin(); PromelaParserNode* name = *opIterAsgn++; int size = evaluateExpr(*opIterAsgn++); - + variable.compound["size"] = size; for (int i = 0; i < size; i++) { variable.compound["value"].array.push_back(Data(0, Data::INTERPRETED)); } - + assert(opIterAsgn == (*nameIter)->operands.end()); _variables.compound[name->value] = variable; @@ -203,8 +222,8 @@ void PromelaDataModel::evaluateDecl(void* ast) { assert(opIter == node->operands.end()); } else if (node->type == DECLLIST) { for (std::list<PromelaParserNode*>::iterator declIter = node->operands.begin(); - declIter != node->operands.end(); - declIter++) { + declIter != node->operands.end(); + declIter++) { evaluateDecl(*declIter); } } else { @@ -216,41 +235,41 @@ int PromelaDataModel::evaluateExpr(void* ast) { PromelaParserNode* node = (PromelaParserNode*)ast; std::list<PromelaParserNode*>::iterator opIter = node->operands.begin(); switch (node->type) { - case CONST: - return strTo<int>(node->value); - case NAME: - case VAR_ARRAY: - return getVariable(node); - case PLUS: - return evaluateExpr(*opIter++) + evaluateExpr(*opIter++); - case MINUS: - return evaluateExpr(*opIter++) - evaluateExpr(*opIter++); - case DIVIDE: - return evaluateExpr(*opIter++) / evaluateExpr(*opIter++); - case MODULO: - return evaluateExpr(*opIter++) % evaluateExpr(*opIter++); - case EQ: - return evaluateExpr(*opIter++) == evaluateExpr(*opIter++); - case LT: - return evaluateExpr(*opIter++) < evaluateExpr(*opIter++); - case LE: - return evaluateExpr(*opIter++) <= evaluateExpr(*opIter++); - case GT: - return evaluateExpr(*opIter++) > evaluateExpr(*opIter++); - case GE: - return evaluateExpr(*opIter++) >= evaluateExpr(*opIter++); - case TIMES: - return evaluateExpr(*opIter++) * evaluateExpr(*opIter++); - case LSHIFT: - return evaluateExpr(*opIter++) << evaluateExpr(*opIter++); - case RSHIFT: - return evaluateExpr(*opIter++) >> evaluateExpr(*opIter++); - case AND: - return evaluateExpr(*opIter++) != 0 && evaluateExpr(*opIter++) != 0; - case OR: - return evaluateExpr(*opIter++) != 0 || evaluateExpr(*opIter++) != 0; - default: - throwErrorExecution("Support for " + PromelaParserNode::typeToDesc(node->type) + " expressions not implemented"); + case CONST: + return strTo<int>(node->value); + case NAME: + case VAR_ARRAY: + return getVariable(node); + case PLUS: + return evaluateExpr(*opIter++) + evaluateExpr(*opIter++); + case MINUS: + return evaluateExpr(*opIter++) - evaluateExpr(*opIter++); + case DIVIDE: + return evaluateExpr(*opIter++) / evaluateExpr(*opIter++); + case MODULO: + return evaluateExpr(*opIter++) % evaluateExpr(*opIter++); + case EQ: + return evaluateExpr(*opIter++) == evaluateExpr(*opIter++); + case LT: + return evaluateExpr(*opIter++) < evaluateExpr(*opIter++); + case LE: + return evaluateExpr(*opIter++) <= evaluateExpr(*opIter++); + case GT: + return evaluateExpr(*opIter++) > evaluateExpr(*opIter++); + case GE: + return evaluateExpr(*opIter++) >= evaluateExpr(*opIter++); + case TIMES: + return evaluateExpr(*opIter++) * evaluateExpr(*opIter++); + case LSHIFT: + return evaluateExpr(*opIter++) << evaluateExpr(*opIter++); + case RSHIFT: + return evaluateExpr(*opIter++) >> evaluateExpr(*opIter++); + case AND: + return evaluateExpr(*opIter++) != 0 && evaluateExpr(*opIter++) != 0; + case OR: + return evaluateExpr(*opIter++) != 0 || evaluateExpr(*opIter++) != 0; + default: + throwErrorExecution("Support for " + PromelaParserNode::typeToDesc(node->type) + " expressions not implemented"); } return 0; } @@ -259,20 +278,20 @@ void PromelaDataModel::evaluateStmnt(void* ast) { PromelaParserNode* node = (PromelaParserNode*)ast; std::list<PromelaParserNode*>::iterator opIter = node->operands.begin(); switch (node->type) { - case ASGN: { - PromelaParserNode* name = *opIter++; - PromelaParserNode* expr = *opIter++; - setVariable(name, evaluateExpr(expr)); - break; - } - case STMNT: { - while(opIter != node->operands.end()) { - evaluateStmnt(*opIter++); - } - break; + case ASGN: { + PromelaParserNode* name = *opIter++; + PromelaParserNode* expr = *opIter++; + setVariable(name, evaluateExpr(expr)); + break; + } + case STMNT: { + while(opIter != node->operands.end()) { + evaluateStmnt(*opIter++); } - default: - throwErrorExecution("No support for " + PromelaParserNode::typeToDesc(node->type) + " statement implemented"); + break; + } + default: + throwErrorExecution("No support for " + PromelaParserNode::typeToDesc(node->type) + " statement implemented"); } } @@ -281,80 +300,104 @@ void PromelaDataModel::setVariable(void* ast, int value) { std::list<PromelaParserNode*>::iterator opIter = node->operands.begin(); switch (node->type) { - case VAR_ARRAY: { - PromelaParserNode* name = *opIter++; - PromelaParserNode* expr = *opIter++; - int index = evaluateExpr(expr); - - if (_variables.compound.find(name->value) == _variables.compound.end()) { - throwErrorExecution("No variable " + name->value + " was declared"); - } - - if (!_variables[name->value].hasKey("size")) { - throwErrorExecution("Variable " + name->value + " is no array"); - } + case VAR_ARRAY: { + PromelaParserNode* name = *opIter++; + PromelaParserNode* expr = *opIter++; + int index = evaluateExpr(expr); - if (strTo<int>(_variables[name->value]["size"].atom) <= index) { - throwErrorExecution("Index " + toStr(index) + " in array " + name->value + "[" + _variables[name->value]["size"].atom + "] is out of bounds"); - } + if (_variables.compound.find(name->value) == _variables.compound.end()) { + throwErrorExecution("No variable " + name->value + " was declared"); + } - _variables.compound[name->value].compound["value"][index] = Data(value, Data::VERBATIM); - - break; + if (!_variables[name->value].hasKey("size")) { + throwErrorExecution("Variable " + name->value + " is no array"); } - case NAME: - _variables.compound[node->value].compound["value"] = Data(value, Data::VERBATIM); - break; - default: - break; + + if (strTo<int>(_variables[name->value]["size"].atom) <= index) { + throwErrorExecution("Index " + toStr(index) + " in array " + name->value + "[" + _variables[name->value]["size"].atom + "] is out of bounds"); + } + + _variables.compound[name->value].compound["value"][index] = Data(value, Data::VERBATIM); + + break; } - + case NAME: + _variables.compound[node->value].compound["value"] = Data(value, Data::VERBATIM); + break; + default: + break; + } + // std::cout << Data::toJSON(_variables) << std::endl; } int PromelaDataModel::getVariable(void* ast) { PromelaParserNode* node = (PromelaParserNode*)ast; // node->dump(); - + std::list<PromelaParserNode*>::iterator opIter = node->operands.begin(); switch(node->type) { - case NAME: - if (_variables.compound.find(node->value) == _variables.compound.end()) { - throwErrorExecution("No variable " + node->value + " was declared"); - } - return strTo<int>(_variables[node->value]["value"]); - case VAR_ARRAY: { - PromelaParserNode* name = *opIter++; - PromelaParserNode* expr = *opIter++; - int index = evaluateExpr(expr); - - if (_variables.compound.find(name->value) == _variables.compound.end()) { - throwErrorExecution("No variable " + name->value + " was declared"); - } - - if (!_variables[name->value].hasKey("size")) { - throwErrorExecution("Variable " + name->value + " is no array"); - } - - if (strTo<int>(_variables[name->value]["size"].atom) <= index) { - throwErrorExecution("Index " + toStr(index) + " in array " + name->value + "[" + _variables[name->value]["size"].atom + "] is out of bounds"); - } - return _variables.compound[name->value].compound["value"][index]; + case NAME: + if (_variables.compound.find(node->value) == _variables.compound.end()) { + throwErrorExecution("No variable " + node->value + " was declared"); } - default: - throwErrorExecution("Retrieving value of " + PromelaParserNode::typeToDesc(node->type) + " variable not implemented"); + if (_variables[node->value].compound.find("size") != _variables[node->value].compound.end()) { + throwErrorExecution("Type error: Variable " + node->value + " is an array"); + } + return strTo<int>(_variables[node->value]["value"].atom); + case VAR_ARRAY: { + PromelaParserNode* name = *opIter++; + PromelaParserNode* expr = *opIter++; + int index = evaluateExpr(expr); + + if (_variables.compound.find(name->value) == _variables.compound.end()) { + throwErrorExecution("No variable " + name->value + " was declared"); + } + + if (!_variables[name->value].hasKey("size")) { + throwErrorExecution("Variable " + name->value + " is no array"); + } + + if (strTo<int>(_variables[name->value]["size"].atom) <= index) { + throwErrorExecution("Index " + toStr(index) + " in array " + name->value + "[" + _variables[name->value]["size"].atom + "] is out of bounds"); + } + return strTo<int>(_variables.compound[name->value].compound["value"][index].atom); + } + default: + throwErrorExecution("Retrieving value of " + PromelaParserNode::typeToDesc(node->type) + " variable not implemented"); } return 0; } +std::string PromelaDataModel::andExpressions(std::list<std::string> expressions) { + + if (expressions.size() == 0) + return ""; + + if (expressions.size() == 1) + return *(expressions.begin()); + + std::ostringstream exprSS; + exprSS << "("; + std::string conjunction = ""; + for (std::list<std::string>::const_iterator exprIter = expressions.begin(); + exprIter != expressions.end(); + exprIter++) { + exprSS << conjunction << "(" << *exprIter << ")"; + conjunction = " && "; + } + exprSS << ")"; + return exprSS.str(); +} + void PromelaDataModel::assign(const std::string& location, const Data& data) { // used for e.g. to assign command line parameters std::cout << "Ignoring " << location << " = " << Data::toJSON(data) << std::endl; } void PromelaDataModel::init(const Element<std::string>& dataElem, - const Node<std::string>& node, - const std::string& content) { + const Node<std::string>& node, + const std::string& content) { // from <datamodel> assign(dataElem, node, content); } diff --git a/src/uscxml/plugins/datamodel/promela/PromelaDataModel.h b/src/uscxml/plugins/datamodel/promela/PromelaDataModel.h index e6a7894..6d7d505 100644 --- a/src/uscxml/plugins/datamodel/promela/PromelaDataModel.h +++ b/src/uscxml/plugins/datamodel/promela/PromelaDataModel.h @@ -75,22 +75,24 @@ public: virtual bool isDeclared(const std::string& expr); virtual Data getStringAsData(const std::string& content); - + virtual std::string evalAsString(const std::string& expr); virtual bool evalAsBool(const Arabica::DOM::Node<std::string>& node, const std::string& expr); virtual bool evalAsBool(const std::string& expr); + virtual std::string andExpressions(std::list<std::string> expressions); + protected: void evaluateDecl(void* ast); int evaluateExpr(void* ast); void evaluateStmnt(void* ast); - + void setVariable(void* ast, int value); int getVariable(void* ast); - + int _lastMType; - + Event _event; std::string _name; std::string _sessionId; diff --git a/src/uscxml/plugins/datamodel/promela/PromelaParser.cpp b/src/uscxml/plugins/datamodel/promela/PromelaParser.cpp index a27d2df..0966396 100644 --- a/src/uscxml/plugins/datamodel/promela/PromelaParser.cpp +++ b/src/uscxml/plugins/datamodel/promela/PromelaParser.cpp @@ -1,19 +1,43 @@ +/** + * @file + * @author 2012-2014 Stefan Radomski (stefan.radomski@cs.tu-darmstadt.de) + * @copyright Simplified BSD + * + * @cond + * This program is free software: you can redistribute it and/or modify + * it under the terms of the FreeBSD license as published by the FreeBSD + * project. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * You should have received a copy of the FreeBSD license along with this + * program. If not, see <http://www.opensource.org/licenses/bsd-license>. + * @endcond + */ + #include "PromelaParser.h" #include "parser/promela.tab.hpp" -struct yy_buffer_state; \ -typedef yy_buffer_state *YY_BUFFER_STATE; \ -extern YY_BUFFER_STATE promela__scan_buffer(char *, size_t, void*); \ -extern int promela_lex (PROMELA_STYPE* yylval_param, void* yyscanner); \ -int promela_lex_init (void**); \ -int promela_lex_destroy (void*); \ +struct yy_buffer_state; +typedef yy_buffer_state *YY_BUFFER_STATE; +extern YY_BUFFER_STATE promela__scan_buffer(char *, size_t, void*); +void promela__delete_buffer(YY_BUFFER_STATE, void*); +YY_BUFFER_STATE promela__scan_string (const char * yystr , void*); + + +extern int promela_lex (PROMELA_STYPE* yylval_param, void* yyscanner); +int promela_lex_init (void**); +int promela_lex_destroy (void*); void promela_error (uscxml::PromelaParser* ctx, void* yyscanner, const char* err) { + // mark as pending exception as we cannot throw from constructor and have the destructor called uscxml::Event excEvent; excEvent.data.compound["exception"] = uscxml::Data(err, uscxml::Data::VERBATIM); excEvent.name = "error.execution"; excEvent.eventType = uscxml::Event::PLATFORM; - throw excEvent; + ctx->pendingException = excEvent; } namespace uscxml { @@ -37,71 +61,187 @@ PromelaParser::PromelaParser(const std::string& expr, Type expectedType) { } void PromelaParser::init(const std::string& expr) { - input_length = expr.length() + 5; // plus some zero terminators + ast = NULL; + input_length = expr.length() + 2; // plus some zero terminators input = (char*) calloc(1, input_length); memcpy(input, expr.c_str(), expr.length()); - + promela_lex_init(&scanner); // promela_assign_set_extra(ast, &scanner); - promela__scan_buffer(input, input_length, scanner); + buffer = promela__scan_string(input, scanner); + // buffer = promela__scan_buffer(input, input_length, scanner); promela_parse(this, scanner); + if (pendingException.name.size() > 0) { + // parsing failed in promela_error + destroy(); + throw pendingException; + } } - -PromelaParser::~PromelaParser() { + +void PromelaParser::destroy() { + if (ast) + delete(ast); free(input); + promela__delete_buffer((YY_BUFFER_STATE)buffer, scanner); promela_lex_destroy(scanner); } +PromelaParser::~PromelaParser() { + destroy(); +} + std::string PromelaParser::typeToDesc(int type) { switch (type) { - case PROMELA_EXPR: return "expression"; - case PROMELA_DECL: return "declarations"; - case PROMELA_STMNT: return "statements"; - default: - break; + case PROMELA_EXPR: + return "expression"; + case PROMELA_DECL: + return "declarations"; + case PROMELA_STMNT: + return "statements"; + default: + break; } return ""; } +PromelaParserNode::~PromelaParserNode() { + while(operands.size() > 0) { + delete operands.front(); + operands.pop_front(); + } +} + +PromelaParserNode* PromelaParser::node(int type, int nrArgs, ...) { + PromelaParserNode* newNode = new PromelaParserNode(); + newNode->type = type; + va_list ap; + va_start(ap, nrArgs); + for(int i = 1; i <= nrArgs; i++) { + newNode->operands.push_back(va_arg(ap, PromelaParserNode*)); + } + return newNode; +} + +PromelaParserNode* PromelaParser::value(int type, const char* value) { + PromelaParserNode* newNode = new PromelaParserNode(); + newNode->value = value; + newNode->type = type; + return newNode; +} + +void PromelaParser::dump() { + switch (type) { + case PROMELA_EXPR: + std::cout << "Promela Expression" << std::endl; + break; + case PROMELA_DECL: + std::cout << "Promela Declarations" << std::endl; + break; + case PROMELA_STMNT: + std::cout << "Promela Statement" << std::endl; + break; + } + ast->dump(); +} + + +void PromelaParserNode::merge(PromelaParserNode* node) { + for (std::list<PromelaParserNode*>::iterator iter = node->operands.begin(); + iter != node->operands.end(); iter++) { + operands.push_back(*iter); + } + node->operands.clear(); +} + +void PromelaParserNode::push(PromelaParserNode* node) { + operands.push_back(node); +} + +void PromelaParserNode::dump(int indent) { + std::string padding; + for (int i = 0; i < indent; i++) { + padding += " "; + } + std::cout << padding << typeToDesc(type) << ": " << value << std::endl; + for (std::list<PromelaParserNode*>::iterator iter = operands.begin(); + iter != operands.end(); iter++) { + (*iter)->dump(indent + 1); + } +} + std::string PromelaParserNode::typeToDesc(int type) { switch(type) { - case PLUS: return "PLUS"; - case MINUS: return "MINUS"; - case TIMES: return "TIMES"; - case DIVIDE: return "DIVIDE"; - case MODULO: return "MODULO"; - case BITAND: return "BITAND"; - case BITXOR: return "BITXOR"; - case BITOR: return "BITOR"; - case GT: return "GT"; - case LT: return "LT"; - case GE: return "GE"; - case LE: return "LE"; - case EQ: return "EQ"; - case NE: return "NE"; - case AND: return "AND"; - case OR: return "OR"; - case LSHIFT: return "LSHIFT"; - case RSHIFT: return "RSHIFT"; - case NEG: return "NEG"; - case ASGN: return "ASGN"; - case INCR: return "INCR"; - case DECR: return "DECR"; - case VAR_ARRAY: return "VAR_ARRAY"; - case DECL: return "DECL"; - case STMNT: return "STMNT"; - case TYPE: return "TYPE"; - case NAME: return "NAME"; - case CONST: return "CONST"; - case PRINT: return "PRINT"; - case SHOW: return "SHOW"; - case EXPR: return "EXPR"; - case VARLIST: return "VARLIST"; - case DECLLIST: return "DECLLIST"; - case NAMELIST: return "NAMELIST"; - - default: - return std::string("UNK(") + toStr(type) + ")"; + case PLUS: + return "PLUS"; + case MINUS: + return "MINUS"; + case TIMES: + return "TIMES"; + case DIVIDE: + return "DIVIDE"; + case MODULO: + return "MODULO"; + case BITAND: + return "BITAND"; + case BITXOR: + return "BITXOR"; + case BITOR: + return "BITOR"; + case GT: + return "GT"; + case LT: + return "LT"; + case GE: + return "GE"; + case LE: + return "LE"; + case EQ: + return "EQ"; + case NE: + return "NE"; + case AND: + return "AND"; + case OR: + return "OR"; + case LSHIFT: + return "LSHIFT"; + case RSHIFT: + return "RSHIFT"; + case NEG: + return "NEG"; + case ASGN: + return "ASGN"; + case INCR: + return "INCR"; + case DECR: + return "DECR"; + case VAR_ARRAY: + return "VAR_ARRAY"; + case DECL: + return "DECL"; + case STMNT: + return "STMNT"; + case TYPE: + return "TYPE"; + case NAME: + return "NAME"; + case CONST: + return "CONST"; + case PRINT: + return "PRINT"; + case SHOW: + return "SHOW"; + case EXPR: + return "EXPR"; + case VARLIST: + return "VARLIST"; + case DECLLIST: + return "DECLLIST"; + case NAMELIST: + return "NAMELIST"; + + default: + return std::string("UNK(") + toStr(type) + ")"; } } diff --git a/src/uscxml/plugins/datamodel/promela/PromelaParser.h b/src/uscxml/plugins/datamodel/promela/PromelaParser.h index 0cca365..9fd0e9a 100644 --- a/src/uscxml/plugins/datamodel/promela/PromelaParser.h +++ b/src/uscxml/plugins/datamodel/promela/PromelaParser.h @@ -1,3 +1,22 @@ +/** + * @file + * @author 2012-2014 Stefan Radomski (stefan.radomski@cs.tu-darmstadt.de) + * @copyright Simplified BSD + * + * @cond + * This program is free software: you can redistribute it and/or modify + * it under the terms of the FreeBSD license as published by the FreeBSD + * project. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * You should have received a copy of the FreeBSD license along with this + * program. If not, see <http://www.opensource.org/licenses/bsd-license>. + * @endcond + */ + // bison -v -d promela-expr.ypp && flex promela-expr.l // bison promela-expr.ypp && flex promela-expr.l @@ -9,105 +28,56 @@ #include "uscxml/Message.h" -#define GRAMMAR_COMMON(name, uc_name) \ -struct yy_buffer_state; \ -typedef yy_buffer_state *YY_BUFFER_STATE; \ -extern YY_BUFFER_STATE promela_##name##__scan_buffer(char *, size_t, void*); \ -extern int promela_##name##_lex (PROMELA_##uc_name##_STYPE* yylval_param, void* yyscanner); \ -int promela_##name##_lex_init (void**); \ -int promela_##name##_lex_destroy (void*); \ - namespace uscxml { class PromelaParser; - + struct PromelaParserNode { PromelaParserNode() : type(0) {} + virtual ~PromelaParserNode(); + + void merge(PromelaParserNode* node); + void push(PromelaParserNode* node); + void dump(int indent = 0); + + static std::string typeToDesc(int type); + int type; std::string value; std::list<PromelaParserNode*> operands; - - void merge(PromelaParserNode* node) { - for (std::list<PromelaParserNode*>::iterator iter = node->operands.begin(); - iter != node->operands.end(); iter++) { - operands.push_back(*iter); - } - } - - void push(PromelaParserNode* node) { - operands.push_back(node); - } - - void dump(int indent = 0) { - std::string padding; - for (int i = 0; i < indent; i++) { - padding += " "; - } - std::cout << padding << typeToDesc(type) << ": " << value << std::endl; - for (std::list<PromelaParserNode*>::iterator iter = operands.begin(); - iter != operands.end(); iter++) { - (*iter)->dump(indent + 1); - } - } - - static std::string typeToDesc(int type); }; class PromelaParser { public: enum Type { - PROMELA_EXPR, - PROMELA_DECL, - PROMELA_STMNT + PROMELA_EXPR, + PROMELA_DECL, + PROMELA_STMNT }; - + static std::string typeToDesc(int type); PromelaParser(const std::string& expr); PromelaParser(const std::string& expr, Type expectedType); virtual ~PromelaParser(); - - virtual PromelaParserNode* node(int type, int nrArgs, ...) { - PromelaParserNode* newNode = new PromelaParserNode(); - newNode->type = type; - va_list ap; - va_start(ap, nrArgs); - for(int i = 1; i <= nrArgs; i++) { - newNode->operands.push_back(va_arg(ap, PromelaParserNode*)); - } - return newNode; - } - - virtual PromelaParserNode* value(int type, const char* value) { - PromelaParserNode* newNode = new PromelaParserNode(); - newNode->value = value; - newNode->type = type; - return newNode; - } - - void dump() { - switch (type) { - case PROMELA_EXPR: - std::cout << "Promela Expression" << std::endl; - break; - case PROMELA_DECL: - std::cout << "Promela Declarations" << std::endl; - break; - case PROMELA_STMNT: - std::cout << "Promela Statement" << std::endl; - break; - } - ast->dump(); - } + + virtual PromelaParserNode* node(int type, int nrArgs, ...); + virtual PromelaParserNode* value(int type, const char* value); + void dump(); + PromelaParserNode* ast; Type type; + Event pendingException; + protected: - + void init(const std::string& expr); - + void destroy(); + + void* buffer; void* scanner; char* input; size_t input_length; 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 f4f9f83..a170089 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,8 +230,8 @@ typedef size_t yy_size_t; #define EOB_ACT_END_OF_FILE 1 #define EOB_ACT_LAST_MATCH 2 - #define YY_LESS_LINENO(n) - +#define YY_LESS_LINENO(n) + /* Return all but the first "n" matched characters back to the input stream. */ #define yyless(n) \ do \ @@ -250,14 +250,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 */ @@ -291,9 +290,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. */ @@ -315,7 +314,7 @@ struct yy_buffer_state */ #define YY_BUFFER_EOF_PENDING 2 - }; +}; #endif /* !YY_STRUCT_YY_BUFFER_STATE */ /* %if-c-only Standard (non-C++) definition */ @@ -438,160 +437,159 @@ static void yy_fatal_error (yyconst char msg[] ,yyscan_t yyscanner ); #define YY_END_OF_BUFFER 45 /* 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[102] = - { 0, - 0, 0, 45, 43, 42, 42, 6, 43, 12, 23, - 43, 31, 32, 10, 13, 29, 14, 28, 11, 39, - 30, 19, 37, 20, 40, 40, 33, 34, 24, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 35, 25, - 36, 7, 42, 21, 0, 38, 0, 26, 0, 41, - 0, 8, 9, 39, 15, 17, 22, 18, 16, 40, - 0, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 27, 0, 41, 0, 1, 40, 40, - 40, 2, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 3, 40, 40, 40, 4, 5, 40, 40, - - 0 - } ; - -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[106] = - { 0, - 0, 0, 141, 142, 49, 51, 120, 50, 142, 132, - 48, 142, 142, 142, 126, 142, 123, 142, 142, 119, - 142, 38, 115, 39, 0, 129, 142, 142, 142, 26, - 105, 93, 100, 86, 87, 28, 86, 88, 142, 78, - 142, 142, 65, 142, 58, 142, 122, 142, 57, 142, - 66, 142, 142, 107, 142, 142, 142, 142, 142, 0, - 65, 79, 82, 77, 83, 75, 79, 71, 81, 75, - 79, 68, 69, 142, 63, 68, 76, 0, 74, 79, - 66, 0, 67, 61, 57, 57, 66, 61, 64, 63, - 48, 45, 0, 54, 48, 46, 0, 0, 50, 48, - - 142, 101, 103, 75, 105 - } ; - -static yyconst flex_int16_t yy_def[106] = - { 0, - 101, 1, 101, 101, 101, 101, 101, 102, 101, 101, - 103, 101, 101, 101, 101, 101, 101, 101, 101, 101, - 101, 101, 101, 101, 104, 104, 101, 101, 101, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 101, 101, - 101, 101, 101, 101, 102, 101, 102, 101, 103, 101, - 105, 101, 101, 101, 101, 101, 101, 101, 101, 104, - 102, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 101, 103, 103, 105, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - - 0, 101, 101, 101, 101 - } ; - -static yyconst flex_int16_t yy_nxt[193] = - { 0, - 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, - 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, - 24, 25, 26, 27, 4, 28, 29, 25, 30, 25, - 25, 31, 25, 25, 32, 25, 33, 34, 25, 25, - 35, 25, 36, 37, 38, 25, 39, 40, 41, 42, - 43, 43, 43, 43, 46, 50, 55, 56, 58, 59, - 62, 70, 46, 71, 50, 63, 43, 43, 49, 46, - 50, 64, 51, 76, 47, 50, 60, 78, 49, 97, - 100, 51, 47, 76, 99, 98, 96, 51, 78, 47, - 77, 95, 51, 78, 93, 94, 93, 93, 92, 91, - - 77, 45, 45, 49, 49, 75, 75, 90, 89, 78, - 78, 88, 87, 86, 85, 84, 83, 82, 78, 81, - 80, 79, 78, 54, 101, 74, 73, 72, 69, 68, - 67, 66, 65, 61, 57, 54, 53, 52, 48, 44, - 101, 3, 101, 101, 101, 101, 101, 101, 101, 101, - 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, - 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, - 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, - 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, - 101, 101 - - } ; - -static yyconst flex_int16_t yy_chk[193] = - { 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, - 30, 36, 45, 36, 49, 30, 43, 43, 51, 61, - 75, 30, 11, 51, 8, 76, 104, 100, 77, 95, - 99, 49, 45, 77, 96, 95, 94, 75, 92, 61, - 51, 91, 76, 90, 89, 88, 87, 86, 85, 84, - - 77, 102, 102, 103, 103, 105, 105, 83, 81, 80, - 79, 73, 72, 71, 70, 69, 68, 67, 66, 65, - 64, 63, 62, 54, 47, 40, 38, 37, 35, 34, - 33, 32, 31, 26, 23, 20, 17, 15, 10, 7, - 3, 101, 101, 101, 101, 101, 101, 101, 101, 101, - 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, - 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, - 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, - 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, - 101, 101 - - } ; - -static yyconst flex_int16_t yy_rule_linenum[44] = - { 0, - 27, 32, 33, 34, 35, 37, 38, 39, 40, 42, - 43, 44, 46, 47, 49, 50, 52, 53, 54, 55, - 57, 58, 60, 61, 62, 65, 66, 68, 69, 70, - 72, 73, 75, 76, 78, 79, 81, 83, 85, 86, - 88, 90, 92 - } ; +}; +static yyconst flex_int16_t yy_accept[102] = { + 0, + 0, 0, 45, 43, 42, 42, 6, 43, 12, 23, + 43, 31, 32, 10, 13, 29, 14, 28, 11, 39, + 30, 19, 37, 20, 40, 40, 33, 34, 24, 40, + 40, 40, 40, 40, 40, 40, 40, 40, 35, 25, + 36, 7, 42, 21, 0, 38, 0, 26, 0, 41, + 0, 8, 9, 39, 15, 17, 22, 18, 16, 40, + 0, 40, 40, 40, 40, 40, 40, 40, 40, 40, + 40, 40, 40, 27, 0, 41, 0, 1, 40, 40, + 40, 2, 40, 40, 40, 40, 40, 40, 40, 40, + 40, 40, 3, 40, 40, 40, 4, 5, 40, 40, + + 0 +} ; + +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[106] = { + 0, + 0, 0, 141, 142, 49, 51, 120, 50, 142, 132, + 48, 142, 142, 142, 126, 142, 123, 142, 142, 119, + 142, 38, 115, 39, 0, 129, 142, 142, 142, 26, + 105, 93, 100, 86, 87, 28, 86, 88, 142, 78, + 142, 142, 65, 142, 58, 142, 122, 142, 57, 142, + 66, 142, 142, 107, 142, 142, 142, 142, 142, 0, + 65, 79, 82, 77, 83, 75, 79, 71, 81, 75, + 79, 68, 69, 142, 63, 68, 76, 0, 74, 79, + 66, 0, 67, 61, 57, 57, 66, 61, 64, 63, + 48, 45, 0, 54, 48, 46, 0, 0, 50, 48, + + 142, 101, 103, 75, 105 +} ; + +static yyconst flex_int16_t yy_def[106] = { + 0, + 101, 1, 101, 101, 101, 101, 101, 102, 101, 101, + 103, 101, 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 104, 104, 101, 101, 101, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 101, 101, + 101, 101, 101, 101, 102, 101, 102, 101, 103, 101, + 105, 101, 101, 101, 101, 101, 101, 101, 101, 104, + 102, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 101, 103, 103, 105, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + + 0, 101, 101, 101, 101 +} ; + +static yyconst flex_int16_t yy_nxt[193] = { + 0, + 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, + 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, + 24, 25, 26, 27, 4, 28, 29, 25, 30, 25, + 25, 31, 25, 25, 32, 25, 33, 34, 25, 25, + 35, 25, 36, 37, 38, 25, 39, 40, 41, 42, + 43, 43, 43, 43, 46, 50, 55, 56, 58, 59, + 62, 70, 46, 71, 50, 63, 43, 43, 49, 46, + 50, 64, 51, 76, 47, 50, 60, 78, 49, 97, + 100, 51, 47, 76, 99, 98, 96, 51, 78, 47, + 77, 95, 51, 78, 93, 94, 93, 93, 92, 91, + + 77, 45, 45, 49, 49, 75, 75, 90, 89, 78, + 78, 88, 87, 86, 85, 84, 83, 82, 78, 81, + 80, 79, 78, 54, 101, 74, 73, 72, 69, 68, + 67, 66, 65, 61, 57, 54, 53, 52, 48, 44, + 101, 3, 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101 + +} ; + +static yyconst flex_int16_t yy_chk[193] = { + 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, + 30, 36, 45, 36, 49, 30, 43, 43, 51, 61, + 75, 30, 11, 51, 8, 76, 104, 100, 77, 95, + 99, 49, 45, 77, 96, 95, 94, 75, 92, 61, + 51, 91, 76, 90, 89, 88, 87, 86, 85, 84, + + 77, 102, 102, 103, 103, 105, 105, 83, 81, 80, + 79, 73, 72, 71, 70, 69, 68, 67, 66, 65, + 64, 63, 62, 54, 47, 40, 38, 37, 35, 34, + 33, 32, 31, 26, 23, 20, 17, 15, 10, 7, + 3, 101, 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101 + +} ; + +static yyconst flex_int16_t yy_rule_linenum[44] = { + 0, + 27, 32, 33, 34, 35, 37, 38, 39, 40, 42, + 43, 44, 46, 47, 49, 50, 52, 53, 54, 55, + 57, 58, 60, 61, 62, 65, 66, 68, 69, 70, + 72, 73, 75, 76, 78, 79, 81, 83, 85, 86, + 88, 90, 92 +} ; /* The intent behind this definition is that it'll catch * any uses of REJECT which flex missed. @@ -605,7 +603,7 @@ static yyconst flex_int16_t yy_rule_linenum[44] = /* see: http://spinroot.com/spin/Man/operators.html */ #define YY_NO_UNISTD_H 1 #line 14 "promela.l" - + #include "../PromelaParser.h" #include "promela.tab.hpp" #define YYSTYPE PROMELA_STYPE @@ -634,40 +632,39 @@ static yyconst flex_int16_t yy_rule_linenum[44] = /* %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; - - }; /* 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; + +}; /* end struct yyguts_t */ /* %if-c-only */ @@ -677,10 +674,10 @@ 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 - +/* This must go here because YYSTYPE and YYLTYPE are included + * from bison output in section 1.*/ +# define yylval yyg->yylval_r + int promela_lex_init (yyscan_t* scanner); int promela_lex_init_extra (YY_EXTRA_TYPE user_defined,yyscan_t* scanner); @@ -740,8 +737,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 */ @@ -871,7 +868,7 @@ static int input (yyscan_t yyscanner ); /* %if-c-only Standard (non-C++) definition */ extern int promela_lex \ - (YYSTYPE * yylval_param ,yyscan_t yyscanner); +(YYSTYPE * yylval_param ,yyscan_t yyscanner); #define YY_DECL int promela_lex \ (YYSTYPE * yylval_param , yyscan_t yyscanner) @@ -900,23 +897,21 @@ 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 25 "promela.l" #line 915 "promela.lex.yy.cpp" - yylval = yylval_param; + yylval = yylval_param; - if ( !yyg->yy_init ) - { + if ( !yyg->yy_init ) { yyg->yy_init = 1; #ifdef YY_USER_INIT @@ -927,31 +922,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. */ @@ -962,43 +956,38 @@ 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 >= 102 ) yy_c = yy_meta[(unsigned int) yy_c]; - } + } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; ++yy_cp; - } - while ( yy_current_state != 101 ); + } while ( yy_current_state != 101 ); 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 */ 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 < 44 ) @@ -1011,377 +1000,369 @@ 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: -YY_RULE_SETUP + case 1: + YY_RULE_SETUP #line 27 "promela.l" -{ - yylval->value = strdup(yytext); - return TYPE; -} - YY_BREAK -case 2: -YY_RULE_SETUP + { + yylval->value = strdup(yytext); + return TYPE; + } + YY_BREAK + case 2: + YY_RULE_SETUP #line 32 "promela.l" -{ return LEN; } - YY_BREAK -case 3: -YY_RULE_SETUP + { return LEN; } + YY_BREAK + case 3: + YY_RULE_SETUP #line 33 "promela.l" -{ yylval->value = strdup(yytext); return CONST; } - YY_BREAK -case 4: -YY_RULE_SETUP + { yylval->value = strdup(yytext); return CONST; } + YY_BREAK + case 4: + YY_RULE_SETUP #line 34 "promela.l" -{ return PRINT; } - YY_BREAK -case 5: -YY_RULE_SETUP + { return PRINT; } + YY_BREAK + case 5: + YY_RULE_SETUP #line 35 "promela.l" -{ return PRINTM; } - YY_BREAK -case 6: -YY_RULE_SETUP + { return PRINTM; } + YY_BREAK + case 6: + YY_RULE_SETUP #line 37 "promela.l" -{ return NEG; } - YY_BREAK -case 7: -YY_RULE_SETUP + { return NEG; } + YY_BREAK + case 7: + YY_RULE_SETUP #line 38 "promela.l" -{ return COMPL; } - YY_BREAK -case 8: -YY_RULE_SETUP + { return COMPL; } + YY_BREAK + case 8: + YY_RULE_SETUP #line 39 "promela.l" -{ return INCR; } - YY_BREAK -case 9: -YY_RULE_SETUP + { return INCR; } + YY_BREAK + case 9: + YY_RULE_SETUP #line 40 "promela.l" -{ return DECR; } - YY_BREAK -case 10: -YY_RULE_SETUP + { return DECR; } + YY_BREAK + case 10: + YY_RULE_SETUP #line 42 "promela.l" -{ return TIMES; } - YY_BREAK -case 11: -YY_RULE_SETUP + { return TIMES; } + YY_BREAK + case 11: + YY_RULE_SETUP #line 43 "promela.l" -{ return DIVIDE; } - YY_BREAK -case 12: -YY_RULE_SETUP + { return DIVIDE; } + YY_BREAK + case 12: + YY_RULE_SETUP #line 44 "promela.l" -{ return MODULO; } - YY_BREAK -case 13: -YY_RULE_SETUP + { return MODULO; } + YY_BREAK + case 13: + YY_RULE_SETUP #line 46 "promela.l" -{ return PLUS; } - YY_BREAK -case 14: -YY_RULE_SETUP + { return PLUS; } + YY_BREAK + case 14: + YY_RULE_SETUP #line 47 "promela.l" -{ return MINUS; } - YY_BREAK -case 15: -YY_RULE_SETUP + { return MINUS; } + YY_BREAK + case 15: + YY_RULE_SETUP #line 49 "promela.l" -{ return LSHIFT; } - YY_BREAK -case 16: -YY_RULE_SETUP + { return LSHIFT; } + YY_BREAK + case 16: + YY_RULE_SETUP #line 50 "promela.l" -{ return RSHIFT; } - YY_BREAK -case 17: -YY_RULE_SETUP + { return RSHIFT; } + YY_BREAK + case 17: + YY_RULE_SETUP #line 52 "promela.l" -{ return LE; } - YY_BREAK -case 18: -YY_RULE_SETUP + { return LE; } + YY_BREAK + case 18: + YY_RULE_SETUP #line 53 "promela.l" -{ return GE; } - YY_BREAK -case 19: -YY_RULE_SETUP + { return GE; } + YY_BREAK + case 19: + YY_RULE_SETUP #line 54 "promela.l" -{ return LT; } - YY_BREAK -case 20: -YY_RULE_SETUP + { return LT; } + YY_BREAK + case 20: + YY_RULE_SETUP #line 55 "promela.l" -{ return GT; } - YY_BREAK -case 21: -YY_RULE_SETUP + { return GT; } + YY_BREAK + case 21: + YY_RULE_SETUP #line 57 "promela.l" -{ return NE; } - YY_BREAK -case 22: -YY_RULE_SETUP + { return NE; } + YY_BREAK + case 22: + YY_RULE_SETUP #line 58 "promela.l" -{ return EQ; } - YY_BREAK -case 23: -YY_RULE_SETUP + { return EQ; } + YY_BREAK + case 23: + YY_RULE_SETUP #line 60 "promela.l" -{ return BITAND; } - YY_BREAK -case 24: -YY_RULE_SETUP + { return BITAND; } + YY_BREAK + case 24: + YY_RULE_SETUP #line 61 "promela.l" -{ return BITXOR; } - YY_BREAK -case 25: -YY_RULE_SETUP + { return BITXOR; } + YY_BREAK + case 25: + YY_RULE_SETUP #line 62 "promela.l" -{ return BITOR; } - YY_BREAK -case 26: -YY_RULE_SETUP + { return BITOR; } + YY_BREAK + case 26: + YY_RULE_SETUP #line 65 "promela.l" -{ return AND; } - YY_BREAK -case 27: -YY_RULE_SETUP + { return AND; } + YY_BREAK + case 27: + YY_RULE_SETUP #line 66 "promela.l" -{ return OR; } - YY_BREAK -case 28: -YY_RULE_SETUP + { return OR; } + YY_BREAK + case 28: + YY_RULE_SETUP #line 68 "promela.l" -{ return DOT; } - YY_BREAK -case 29: -YY_RULE_SETUP + { return DOT; } + YY_BREAK + case 29: + YY_RULE_SETUP #line 69 "promela.l" -{ return COMMA; } - YY_BREAK -case 30: -YY_RULE_SETUP + { return COMMA; } + YY_BREAK + case 30: + YY_RULE_SETUP #line 70 "promela.l" -{ return SEMI; } - YY_BREAK -case 31: -YY_RULE_SETUP + { return SEMI; } + YY_BREAK + case 31: + YY_RULE_SETUP #line 72 "promela.l" -{ return '('; } - YY_BREAK -case 32: -YY_RULE_SETUP + { return '('; } + YY_BREAK + case 32: + YY_RULE_SETUP #line 73 "promela.l" -{ return ')'; } - YY_BREAK -case 33: -YY_RULE_SETUP + { return ')'; } + YY_BREAK + case 33: + YY_RULE_SETUP #line 75 "promela.l" -{ return '['; } - YY_BREAK -case 34: -YY_RULE_SETUP + { return '['; } + YY_BREAK + case 34: + YY_RULE_SETUP #line 76 "promela.l" -{ return ']'; } - YY_BREAK -case 35: -YY_RULE_SETUP + { return ']'; } + YY_BREAK + case 35: + YY_RULE_SETUP #line 78 "promela.l" -{ return '{'; } - YY_BREAK -case 36: -YY_RULE_SETUP + { return '{'; } + YY_BREAK + case 36: + YY_RULE_SETUP #line 79 "promela.l" -{ return '}'; } - YY_BREAK -case 37: -YY_RULE_SETUP + { return '}'; } + YY_BREAK + case 37: + YY_RULE_SETUP #line 81 "promela.l" -{ return ASGN; } - YY_BREAK -case 38: -/* rule 38 can match eol */ -YY_RULE_SETUP + { return ASGN; } + YY_BREAK + case 38: + /* rule 38 can match eol */ + YY_RULE_SETUP #line 83 "promela.l" -{ yylval->value = strdup(yytext); return(STRING); } - YY_BREAK -case 39: -YY_RULE_SETUP + { yylval->value = strdup(yytext); return(STRING); } + YY_BREAK + case 39: + YY_RULE_SETUP #line 85 "promela.l" -{ yylval->value = strdup(yytext); return CONST; } - YY_BREAK -case 40: -YY_RULE_SETUP + { yylval->value = strdup(yytext); return CONST; } + YY_BREAK + case 40: + YY_RULE_SETUP #line 86 "promela.l" -{ yylval->value = strdup(yytext); return NAME; } - YY_BREAK -case 41: -/* rule 41 can match eol */ -YY_RULE_SETUP + { yylval->value = strdup(yytext); return NAME; } + YY_BREAK + case 41: + /* rule 41 can match eol */ + YY_RULE_SETUP #line 88 "promela.l" -{ } - YY_BREAK -case 42: -/* rule 42 can match eol */ -YY_RULE_SETUP + { } + YY_BREAK + case 42: + /* rule 42 can match eol */ + YY_RULE_SETUP #line 90 "promela.l" -/* eat up whitespace */ - YY_BREAK -case 43: -YY_RULE_SETUP + /* eat up whitespace */ + YY_BREAK + case 43: + YY_RULE_SETUP #line 92 "promela.l" -{ /*printf( "Unrecognized character: %s\n", yytext ); */ } - YY_BREAK -case 44: -YY_RULE_SETUP + { /*printf( "Unrecognized character: %s\n", yytext ); */ } + YY_BREAK + case 44: + YY_RULE_SETUP #line 93 "promela.l" -ECHO; - YY_BREAK + ECHO; + YY_BREAK #line 1253 "promela.lex.yy.cpp" -case YY_STATE_EOF(INITIAL): - yyterminate(); + 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_END_OF_BUFFER: { + /* Amount of text matched not including the EOB char. */ + int yy_amount_of_matched_text = (int) (yy_cp - yyg->yytext_ptr) - 1; - /* Undo the effects of YY_DO_BEFORE_ACTION. */ - *yy_cp = yyg->yy_hold_char; - YY_RESTORE_YY_MORE_OFFSET - - if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_NEW ) - { - /* We're scanning a new file or input source. It's - * possible that this happened because the user - * just pointed yyin at a new source and called - * promela_lex(). If so, then we have to assure - * consistency between YY_CURRENT_BUFFER and our - * globals. Here is the right place to do so, because - * this is the first action (other than possibly a - * back-up) that will match for the new input source. - */ - yyg->yy_n_chars = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; - YY_CURRENT_BUFFER_LVALUE->yy_input_file = yyin; - YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL; + /* 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 */ @@ -1405,7 +1386,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; @@ -1413,26 +1394,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. */ @@ -1448,22 +1427,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 ) @@ -1472,49 +1449,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; @@ -1541,35 +1514,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 >= 102 ) 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; } @@ -1580,28 +1550,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 >= 102 ) yy_c = yy_meta[(unsigned int) yy_c]; - } + } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; yy_is_jam = (yy_current_state == 101); @@ -1610,27 +1578,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; @@ -1638,15 +1606,15 @@ 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 */ yyg->yytext_ptr = yy_bp; yyg->yy_hold_char = *yy_cp; @@ -1659,9 +1627,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 */ @@ -1669,12 +1637,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. @@ -1683,55 +1650,53 @@ 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 */ return c; } @@ -1745,17 +1710,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); @@ -1767,29 +1732,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 ); @@ -1808,7 +1772,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; @@ -1822,13 +1786,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()" ); @@ -1854,12 +1818,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; @@ -1885,36 +1849,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; } @@ -1923,12 +1887,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; @@ -1963,20 +1927,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) @@ -2000,7 +1963,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; @@ -2027,38 +1990,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()" ); @@ -2074,15 +2037,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; @@ -2115,9 +2077,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 */ @@ -2130,12 +2091,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 ); @@ -2165,9 +2125,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 */ @@ -2199,10 +2158,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 */ @@ -2210,64 +2168,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 */ @@ -2276,10 +2228,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 */ @@ -2288,30 +2239,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); - /* 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; + 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 @@ -2320,28 +2269,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 */ @@ -2351,16 +2296,14 @@ 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; } /* %endif */ @@ -2375,22 +2318,22 @@ void promela_set_lval (YYSTYPE * yylval_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 @@ -2404,76 +2347,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); @@ -2483,20 +2424,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 */ @@ -2505,8 +2446,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]; @@ -2514,8 +2454,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 ) ; @@ -2524,13 +2463,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 @@ -2541,8 +2478,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 5cdcec1..6e786cd 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. */ @@ -128,96 +128,95 @@ 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 { - VAR_ARRAY = 258, - VARLIST = 259, - DECL = 260, - DECLLIST = 261, - STMNT = 262, - COLON = 263, - EXPR = 264, - NAMELIST = 265, - ASSERT = 266, - PRINT = 267, - PRINTM = 268, - LEN = 269, - STRING = 270, - TYPEDEF = 271, - MTYPE = 272, - INLINE = 273, - RETURN = 274, - LABEL = 275, - OF = 276, - GOTO = 277, - BREAK = 278, - ELSE = 279, - SEMI = 280, - ARROW = 281, - IF = 282, - FI = 283, - DO = 284, - OD = 285, - FOR = 286, - SELECT = 287, - IN = 288, - SEP = 289, - DOTDOT = 290, - HIDDEN = 291, - SHOW = 292, - ISLOCAL = 293, - CONST = 294, - TYPE = 295, - XU = 296, - NAME = 297, - UNAME = 298, - PNAME = 299, - INAME = 300, - CLAIM = 301, - TRACE = 302, - INIT = 303, - LTL = 304, - COMMA = 305, - ASGN = 306, - AND = 307, - OR = 308, - BITAND = 309, - BITXOR = 310, - BITOR = 311, - NE = 312, - EQ = 313, - LE = 314, - GE = 315, - LT = 316, - GT = 317, - RSHIFT = 318, - LSHIFT = 319, - MINUS = 320, - PLUS = 321, - MODULO = 322, - DIVIDE = 323, - TIMES = 324, - DECR = 325, - INCR = 326, - COMPL = 327, - NEG = 328, - DOT = 329 - }; +/* Put the tokens into the symbol table, so that GDB and other debuggers + know about them. */ +enum promela_tokentype { + VAR_ARRAY = 258, + VARLIST = 259, + DECL = 260, + DECLLIST = 261, + STMNT = 262, + COLON = 263, + EXPR = 264, + NAMELIST = 265, + ASSERT = 266, + PRINT = 267, + PRINTM = 268, + LEN = 269, + STRING = 270, + TYPEDEF = 271, + MTYPE = 272, + INLINE = 273, + RETURN = 274, + LABEL = 275, + OF = 276, + GOTO = 277, + BREAK = 278, + ELSE = 279, + SEMI = 280, + ARROW = 281, + IF = 282, + FI = 283, + DO = 284, + OD = 285, + FOR = 286, + SELECT = 287, + IN = 288, + SEP = 289, + DOTDOT = 290, + HIDDEN = 291, + SHOW = 292, + ISLOCAL = 293, + CONST = 294, + TYPE = 295, + XU = 296, + NAME = 297, + UNAME = 298, + PNAME = 299, + INAME = 300, + CLAIM = 301, + TRACE = 302, + INIT = 303, + LTL = 304, + COMMA = 305, + ASGN = 306, + AND = 307, + OR = 308, + BITAND = 309, + BITXOR = 310, + BITOR = 311, + NE = 312, + EQ = 313, + LE = 314, + GE = 315, + LT = 316, + GT = 317, + RSHIFT = 318, + LSHIFT = 319, + MINUS = 320, + PLUS = 321, + MODULO = 322, + DIVIDE = 323, + TIMES = 324, + DECR = 325, + INCR = 326, + COMPL = 327, + NEG = 328, + DOT = 329 +}; #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 38 "promela.ypp" - uscxml::PromelaParserNode* node; + uscxml::PromelaParserNode* node; char* value; -/* Line 387 of yacc.c */ + /* Line 387 of yacc.c */ #line 222 "promela.tab.cpp" } PROMELA_STYPE; # define PROMELA_STYPE_IS_TRIVIAL 1 @@ -333,10 +332,10 @@ YYID (int yyi) #else static int YYID (yyi) - int yyi; +int yyi; #endif { - return yyi; + return yyi; } #endif @@ -360,7 +359,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 @@ -370,13 +369,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 @@ -416,10 +415,9 @@ 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; +union yyalloc { + yytype_int16 yyss_alloc; + YYSTYPE yyvs_alloc; }; /* The size of the maximum gap between one aligned stack and the next. */ @@ -493,270 +491,257 @@ 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 +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 }; #if PROMELA_DEBUG /* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in YYRHS. */ -static const yytype_uint16 yyprhs[] = -{ - 0, 0, 3, 5, 7, 9, 11, 13, 18, 19, - 23, 24, 27, 31, 35, 39, 43, 47, 51, 55, - 59, 63, 67, 71, 75, 79, 83, 87, 91, 95, - 99, 103, 106, 109, 114, 116, 118, 119, 121, 123, - 125, 129, 133, 140, 142, 145, 149, 151, 155, 157, - 161, 163, 167, 172, 174, 177, 181, 185, 189, 193, - 197, 201, 203, 206, 209, 211, 214, 218, 220, 224, - 227, 230, 236, 241, 246, 249, 251, 252, 261, 262, - 264, 265, 268, 270 +static const yytype_uint16 yyprhs[] = { + 0, 0, 3, 5, 7, 9, 11, 13, 18, 19, + 23, 24, 27, 31, 35, 39, 43, 47, 51, 55, + 59, 63, 67, 71, 75, 79, 83, 87, 91, 95, + 99, 103, 106, 109, 114, 116, 118, 119, 121, 123, + 125, 129, 133, 140, 142, 145, 149, 151, 155, 157, + 161, 163, 167, 172, 174, 177, 181, 185, 189, 193, + 197, 201, 203, 206, 209, 211, 214, 218, 220, 224, + 227, 230, 236, 241, 246, 249, 251, 252, 261, 262, + 264, 265, 268, 270 }; /* YYRHS -- A `-1'-separated list of the rules' RHS. */ -static const yytype_int8 yyrhs[] = -{ - 82, 0, -1, 91, -1, 88, -1, 97, -1, 85, - -1, 48, -1, 48, 13, 88, 14, -1, -1, 84, - 86, 87, -1, -1, 80, 85, -1, 11, 88, 12, - -1, 88, 72, 88, -1, 88, 71, 88, -1, 88, - 75, 88, -1, 88, 74, 88, -1, 88, 73, 88, - -1, 88, 60, 88, -1, 88, 61, 88, -1, 88, - 62, 88, -1, 88, 68, 88, -1, 88, 67, 88, - -1, 88, 66, 88, -1, 88, 65, 88, -1, 88, - 64, 88, -1, 88, 63, 88, -1, 88, 58, 88, - -1, 88, 59, 88, -1, 88, 70, 88, -1, 88, - 69, 88, -1, 79, 88, -1, 71, 88, -1, 20, - 11, 83, 12, -1, 83, -1, 45, -1, -1, 42, - -1, 43, -1, 44, -1, 89, 46, 92, -1, 89, - 49, 92, -1, 89, 46, 57, 15, 96, 16, -1, - 90, -1, 90, 31, -1, 90, 31, 91, -1, 93, - -1, 93, 56, 92, -1, 94, -1, 94, 57, 88, - -1, 48, -1, 48, 8, 45, -1, 48, 13, 95, - 14, -1, 45, -1, 71, 95, -1, 11, 95, 12, - -1, 95, 72, 95, -1, 95, 71, 95, -1, 95, - 75, 95, -1, 95, 74, 95, -1, 95, 73, 95, - -1, 48, -1, 96, 48, -1, 96, 56, -1, 98, - -1, 98, 31, -1, 98, 31, 97, -1, 99, -1, - 83, 57, 88, -1, 83, 77, -1, 83, 76, -1, - 18, 11, 21, 102, 12, -1, 19, 11, 83, 12, - -1, 19, 11, 45, 12, -1, 17, 88, -1, 88, - -1, -1, 83, 57, 51, 100, 11, 101, 12, 99, - -1, -1, 103, -1, -1, 56, 103, -1, 88, -1, - 88, 56, 103, -1 +static const yytype_int8 yyrhs[] = { + 82, 0, -1, 91, -1, 88, -1, 97, -1, 85, + -1, 48, -1, 48, 13, 88, 14, -1, -1, 84, + 86, 87, -1, -1, 80, 85, -1, 11, 88, 12, + -1, 88, 72, 88, -1, 88, 71, 88, -1, 88, + 75, 88, -1, 88, 74, 88, -1, 88, 73, 88, + -1, 88, 60, 88, -1, 88, 61, 88, -1, 88, + 62, 88, -1, 88, 68, 88, -1, 88, 67, 88, + -1, 88, 66, 88, -1, 88, 65, 88, -1, 88, + 64, 88, -1, 88, 63, 88, -1, 88, 58, 88, + -1, 88, 59, 88, -1, 88, 70, 88, -1, 88, + 69, 88, -1, 79, 88, -1, 71, 88, -1, 20, + 11, 83, 12, -1, 83, -1, 45, -1, -1, 42, + -1, 43, -1, 44, -1, 89, 46, 92, -1, 89, + 49, 92, -1, 89, 46, 57, 15, 96, 16, -1, + 90, -1, 90, 31, -1, 90, 31, 91, -1, 93, + -1, 93, 56, 92, -1, 94, -1, 94, 57, 88, + -1, 48, -1, 48, 8, 45, -1, 48, 13, 95, + 14, -1, 45, -1, 71, 95, -1, 11, 95, 12, + -1, 95, 72, 95, -1, 95, 71, 95, -1, 95, + 75, 95, -1, 95, 74, 95, -1, 95, 73, 95, + -1, 48, -1, 96, 48, -1, 96, 56, -1, 98, + -1, 98, 31, -1, 98, 31, 97, -1, 99, -1, + 83, 57, 88, -1, 83, 77, -1, 83, 76, -1, + 18, 11, 21, 102, 12, -1, 19, 11, 83, 12, + -1, 19, 11, 45, 12, -1, 17, 88, -1, 88, + -1, -1, 83, 57, 51, 100, 11, 101, 12, 99, + -1, -1, 103, -1, -1, 56, 103, -1, 88, -1, + 88, 56, 103, -1 }; /* YYRLINE[YYN] -- source line where rule number YYN was defined. */ -static const yytype_uint8 yyrline[] = -{ - 0, 84, 84, 88, 92, 98, 101, 102, 105, 105, - 109, 110, 120, 121, 122, 123, 124, 125, 126, 127, - 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, - 138, 139, 140, 142, 143, 144, 148, 149, 150, 151, - 154, 155, 156, 159, 160, 161, 171, 172, 175, 176, - 179, 180, 181, 184, 185, 186, 187, 188, 189, 190, - 191, 194, 195, 203, 206, 207, 208, 211, 214, 215, - 216, 217, 218, 219, 220, 221, 222, 222, 225, 226, - 229, 230, 233, 234 +static const yytype_uint8 yyrline[] = { + 0, 84, 84, 88, 92, 98, 101, 102, 105, 105, + 109, 110, 120, 121, 122, 123, 124, 125, 126, 127, + 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, + 138, 139, 140, 142, 143, 144, 148, 149, 150, 151, + 154, 155, 156, 159, 160, 161, 171, 172, 175, 176, + 179, 180, 181, 184, 185, 186, 187, 188, 189, 190, + 191, 194, 195, 204, 207, 208, 209, 212, 215, 216, + 217, 218, 219, 220, 221, 222, 223, 223, 226, 227, + 230, 231, 234, 235 }; #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", "VAR_ARRAY", "VARLIST", "DECL", - "DECLLIST", "STMNT", "COLON", "EXPR", "NAMELIST", "'('", "')'", "'['", - "']'", "'{'", "'}'", "ASSERT", "PRINT", "PRINTM", "LEN", "STRING", - "TYPEDEF", "MTYPE", "INLINE", "RETURN", "LABEL", "OF", "GOTO", "BREAK", - "ELSE", "SEMI", "ARROW", "IF", "FI", "DO", "OD", "FOR", "SELECT", "IN", - "SEP", "DOTDOT", "HIDDEN", "SHOW", "ISLOCAL", "CONST", "TYPE", "XU", - "NAME", "UNAME", "PNAME", "INAME", "CLAIM", "TRACE", "INIT", "LTL", - "COMMA", "ASGN", "AND", "OR", "BITAND", "BITXOR", "BITOR", "NE", "EQ", - "LE", "GE", "LT", "GT", "RSHIFT", "LSHIFT", "MINUS", "PLUS", "MODULO", - "DIVIDE", "TIMES", "DECR", "INCR", "COMPL", "NEG", "DOT", "$accept", - "program", "varref", "pfld", "cmpnd", "$@1", "sfld", "expr", "vis", - "one_decl", "decl_lst", "var_list", "ivar", "vardcl", "const_expr", - "nlst", "stmnt_lst", "stmnt", "Stmnt", "$@2", "args", "prargs", "arg", YY_NULL +static const char *const yytname[] = { + "$end", "error", "$undefined", "VAR_ARRAY", "VARLIST", "DECL", + "DECLLIST", "STMNT", "COLON", "EXPR", "NAMELIST", "'('", "')'", "'['", + "']'", "'{'", "'}'", "ASSERT", "PRINT", "PRINTM", "LEN", "STRING", + "TYPEDEF", "MTYPE", "INLINE", "RETURN", "LABEL", "OF", "GOTO", "BREAK", + "ELSE", "SEMI", "ARROW", "IF", "FI", "DO", "OD", "FOR", "SELECT", "IN", + "SEP", "DOTDOT", "HIDDEN", "SHOW", "ISLOCAL", "CONST", "TYPE", "XU", + "NAME", "UNAME", "PNAME", "INAME", "CLAIM", "TRACE", "INIT", "LTL", + "COMMA", "ASGN", "AND", "OR", "BITAND", "BITXOR", "BITOR", "NE", "EQ", + "LE", "GE", "LT", "GT", "RSHIFT", "LSHIFT", "MINUS", "PLUS", "MODULO", + "DIVIDE", "TIMES", "DECR", "INCR", "COMPL", "NEG", "DOT", "$accept", + "program", "varref", "pfld", "cmpnd", "$@1", "sfld", "expr", "vis", + "one_decl", "decl_lst", "var_list", "ivar", "vardcl", "const_expr", + "nlst", "stmnt_lst", "stmnt", "Stmnt", "$@2", "args", "prargs", "arg", YY_NULL }; #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 +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 }; # endif /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ -static const yytype_uint8 yyr1[] = -{ - 0, 81, 82, 82, 82, 83, 84, 84, 86, 85, - 87, 87, 88, 88, 88, 88, 88, 88, 88, 88, - 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, - 88, 88, 88, 88, 88, 88, 89, 89, 89, 89, - 90, 90, 90, 91, 91, 91, 92, 92, 93, 93, - 94, 94, 94, 95, 95, 95, 95, 95, 95, 95, - 95, 96, 96, 96, 97, 97, 97, 98, 99, 99, - 99, 99, 99, 99, 99, 99, 100, 99, 101, 101, - 102, 102, 103, 103 +static const yytype_uint8 yyr1[] = { + 0, 81, 82, 82, 82, 83, 84, 84, 86, 85, + 87, 87, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 89, 89, 89, 89, + 90, 90, 90, 91, 91, 91, 92, 92, 93, 93, + 94, 94, 94, 95, 95, 95, 95, 95, 95, 95, + 95, 96, 96, 96, 97, 97, 97, 98, 99, 99, + 99, 99, 99, 99, 99, 99, 100, 99, 101, 101, + 102, 102, 103, 103 }; /* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */ -static const yytype_uint8 yyr2[] = -{ - 0, 2, 1, 1, 1, 1, 1, 4, 0, 3, - 0, 2, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 2, 2, 4, 1, 1, 0, 1, 1, 1, - 3, 3, 6, 1, 2, 3, 1, 3, 1, 3, - 1, 3, 4, 1, 2, 3, 3, 3, 3, 3, - 3, 1, 2, 2, 1, 2, 3, 1, 3, 2, - 2, 5, 4, 4, 2, 1, 0, 8, 0, 1, - 0, 2, 1, 3 +static const yytype_uint8 yyr2[] = { + 0, 2, 1, 1, 1, 1, 1, 4, 0, 3, + 0, 2, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 2, 2, 4, 1, 1, 0, 1, 1, 1, + 3, 3, 6, 1, 2, 3, 1, 3, 1, 3, + 1, 3, 4, 1, 2, 3, 3, 3, 3, 3, + 3, 1, 2, 2, 1, 2, 3, 1, 3, 2, + 2, 5, 4, 4, 2, 1, 0, 8, 0, 1, + 0, 2, 1, 3 }; /* YYDEFACT[STATE-NAME] -- Default reduction number in state STATE-NUM. Performed when YYTABLE doesn't specify something else to do. Zero means the default is an error. */ -static const yytype_uint8 yydefact[] = -{ - 36, 0, 0, 0, 0, 0, 37, 38, 39, 35, - 6, 0, 0, 0, 34, 8, 5, 3, 0, 43, - 2, 4, 64, 67, 34, 0, 74, 0, 0, 0, - 0, 32, 31, 1, 0, 70, 69, 10, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 36, 65, - 12, 80, 0, 0, 0, 0, 76, 68, 0, 9, - 27, 28, 18, 19, 20, 26, 25, 24, 23, 22, - 21, 30, 29, 14, 13, 17, 16, 15, 50, 0, - 40, 46, 48, 41, 45, 75, 66, 0, 0, 73, - 72, 33, 7, 0, 11, 0, 0, 0, 0, 0, - 82, 81, 71, 78, 51, 0, 53, 0, 0, 61, - 0, 47, 49, 0, 0, 79, 0, 54, 52, 0, - 0, 0, 0, 0, 42, 62, 63, 83, 0, 55, - 57, 56, 60, 59, 58, 77 +static const yytype_uint8 yydefact[] = { + 36, 0, 0, 0, 0, 0, 37, 38, 39, 35, + 6, 0, 0, 0, 34, 8, 5, 3, 0, 43, + 2, 4, 64, 67, 34, 0, 74, 0, 0, 0, + 0, 32, 31, 1, 0, 70, 69, 10, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 36, 65, + 12, 80, 0, 0, 0, 0, 76, 68, 0, 9, + 27, 28, 18, 19, 20, 26, 25, 24, 23, 22, + 21, 30, 29, 14, 13, 17, 16, 15, 50, 0, + 40, 46, 48, 41, 45, 75, 66, 0, 0, 73, + 72, 33, 7, 0, 11, 0, 0, 0, 0, 0, + 82, 81, 71, 78, 51, 0, 53, 0, 0, 61, + 0, 47, 49, 0, 0, 79, 0, 54, 52, 0, + 0, 0, 0, 0, 42, 62, 63, 83, 0, 55, + 57, 56, 60, 59, 58, 77 }; /* YYDEFGOTO[NTERM-NUM]. */ -static const yytype_int8 yydefgoto[] = -{ - -1, 13, 24, 15, 16, 37, 69, 110, 18, 19, - 20, 90, 91, 92, 118, 120, 21, 22, 23, 103, - 124, 98, 111 +static const yytype_int8 yydefgoto[] = { + -1, 13, 24, 15, 16, 37, 69, 110, 18, 19, + 20, 90, 91, 92, 118, 120, 21, 22, 23, 103, + 124, 98, 111 }; /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing STATE-NUM. */ #define YYPACT_NINF -109 -static const yytype_int16 yypact[] = -{ - 46, 65, 65, -5, 7, 9, -109, -109, -109, -109, - 8, 65, 65, 33, -53, -109, -109, 155, -36, 5, - -109, -109, 6, -109, -109, 87, 193, 54, -29, 36, - 65, -1, -109, -109, 60, -109, -109, 13, 65, 65, - 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, - 65, 65, 65, 65, 65, 65, -40, 38, 35, 50, - -109, 25, 71, 75, 84, 110, -109, 193, 36, -109, - 209, 209, 222, 222, 222, 170, 170, 229, 229, 229, - 229, -46, -46, -1, -1, -109, -109, -109, 1, 82, - -109, 51, 49, -109, -109, 193, -109, 65, 100, -109, - -109, -109, -109, 103, -109, 70, 11, 68, 38, 65, - 136, -109, -109, 65, -109, 11, -109, 11, 116, -109, - 44, -109, 193, 65, 106, -109, 92, 28, -109, 11, - 11, 11, 11, 11, -109, -109, -109, -109, 50, -109, - 28, 28, -109, -109, -109, -109 +static const yytype_int16 yypact[] = { + 46, 65, 65, -5, 7, 9, -109, -109, -109, -109, + 8, 65, 65, 33, -53, -109, -109, 155, -36, 5, + -109, -109, 6, -109, -109, 87, 193, 54, -29, 36, + 65, -1, -109, -109, 60, -109, -109, 13, 65, 65, + 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, + 65, 65, 65, 65, 65, 65, -40, 38, 35, 50, + -109, 25, 71, 75, 84, 110, -109, 193, 36, -109, + 209, 209, 222, 222, 222, 170, 170, 229, 229, 229, + 229, -46, -46, -1, -1, -109, -109, -109, 1, 82, + -109, 51, 49, -109, -109, 193, -109, 65, 100, -109, + -109, -109, -109, 103, -109, 70, 11, 68, 38, 65, + 136, -109, -109, 65, -109, 11, -109, 11, 116, -109, + 44, -109, 193, 65, 106, -109, 92, 28, -109, 11, + 11, 11, 11, 11, -109, -109, -109, -109, 50, -109, + 28, 28, -109, -109, -109, -109 }; /* YYPGOTO[NTERM-NUM]. */ -static const yytype_int8 yypgoto[] = -{ - -109, -109, 3, -109, 52, -109, -109, 0, -109, -109, - 61, -50, -109, -109, 117, -109, 63, -109, -15, -109, - -109, -109, -108 +static const yytype_int8 yypgoto[] = { + -109, -109, 3, -109, 52, -109, -109, 0, -109, -109, + 61, -50, -109, -109, 117, -109, 63, -109, -15, -109, + -109, -109, -108 }; /* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If positive, shift that token. If negative, reduce the rule which number is the opposite. If YYTABLE_NINF, syntax error. */ #define YYTABLE_NINF -76 -static const yytype_int16 yytable[] = -{ - 17, 25, 26, 14, 34, 125, 27, 93, 88, 105, - 56, 31, 32, 57, 106, 137, 62, 89, 28, 10, - 29, 30, 115, 35, 36, 51, 52, 53, 54, 55, - 65, 63, 64, 33, 67, -44, 58, 59, 70, 71, - 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, - 82, 83, 84, 85, 86, 87, 116, 1, 121, 95, - 134, 1, 14, 2, 3, 4, 5, 2, 3, 4, - 5, 1, 53, 54, 55, 61, 1, 6, 7, 8, - 5, 97, 117, 99, 10, 5, 88, 100, 6, 7, - 8, 9, 135, 68, 10, 9, 101, 107, 10, 60, - 136, 131, 132, 133, 139, 9, 109, 108, 10, 122, - 9, 66, 112, 10, 113, 114, 119, 11, 138, 94, - 104, 11, 96, 145, 102, 12, 0, 0, 0, 12, - 128, 11, 0, 0, 0, 0, 11, 0, 95, 12, - 0, 14, 0, 0, 12, 38, 39, 40, 41, 42, - 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, - 53, 54, 55, 129, 130, 131, 132, 133, 38, 39, - 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, - 50, 51, 52, 53, 54, 55, -75, 129, 130, 131, - 132, 133, 123, 0, 38, 39, 40, 41, 42, 43, - 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, - 54, 55, 0, 38, 39, 40, 41, 42, 43, 44, - 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, - 55, 0, 126, 0, 127, 45, 46, 47, 48, 49, - 50, 51, 52, 53, 54, 55, 140, 141, 142, 143, - 144, 38, 39, 40, 41, 42, 43, 44, 45, 46, - 47, 48, 49, 50, 51, 52, 53, 54, 55, 40, - 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, - 51, 52, 53, 54, 55, 43, 44, 45, 46, 47, - 48, 49, 50, 51, 52, 53, 54, 55, 49, 50, - 51, 52, 53, 54, 55 +static const yytype_int16 yytable[] = { + 17, 25, 26, 14, 34, 125, 27, 93, 88, 105, + 56, 31, 32, 57, 106, 137, 62, 89, 28, 10, + 29, 30, 115, 35, 36, 51, 52, 53, 54, 55, + 65, 63, 64, 33, 67, -44, 58, 59, 70, 71, + 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, + 82, 83, 84, 85, 86, 87, 116, 1, 121, 95, + 134, 1, 14, 2, 3, 4, 5, 2, 3, 4, + 5, 1, 53, 54, 55, 61, 1, 6, 7, 8, + 5, 97, 117, 99, 10, 5, 88, 100, 6, 7, + 8, 9, 135, 68, 10, 9, 101, 107, 10, 60, + 136, 131, 132, 133, 139, 9, 109, 108, 10, 122, + 9, 66, 112, 10, 113, 114, 119, 11, 138, 94, + 104, 11, 96, 145, 102, 12, 0, 0, 0, 12, + 128, 11, 0, 0, 0, 0, 11, 0, 95, 12, + 0, 14, 0, 0, 12, 38, 39, 40, 41, 42, + 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, + 53, 54, 55, 129, 130, 131, 132, 133, 38, 39, + 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, + 50, 51, 52, 53, 54, 55, -75, 129, 130, 131, + 132, 133, 123, 0, 38, 39, 40, 41, 42, 43, + 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, + 54, 55, 0, 38, 39, 40, 41, 42, 43, 44, + 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, + 55, 0, 126, 0, 127, 45, 46, 47, 48, 49, + 50, 51, 52, 53, 54, 55, 140, 141, 142, 143, + 144, 38, 39, 40, 41, 42, 43, 44, 45, 46, + 47, 48, 49, 50, 51, 52, 53, 54, 55, 40, + 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, + 51, 52, 53, 54, 55, 43, 44, 45, 46, 47, + 48, 49, 50, 51, 52, 53, 54, 55, 49, 50, + 51, 52, 53, 54, 55 }; #define yypact_value_is_default(Yystate) \ @@ -765,60 +750,58 @@ static const yytype_int16 yytable[] = #define yytable_value_is_error(Yytable_value) \ YYID (0) -static const yytype_int16 yycheck[] = -{ - 0, 1, 2, 0, 57, 113, 11, 57, 48, 8, - 46, 11, 12, 49, 13, 123, 45, 57, 11, 48, - 11, 13, 11, 76, 77, 71, 72, 73, 74, 75, - 30, 28, 29, 0, 34, 0, 31, 31, 38, 39, - 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, - 50, 51, 52, 53, 54, 55, 45, 11, 108, 59, - 16, 11, 59, 17, 18, 19, 20, 17, 18, 19, - 20, 11, 73, 74, 75, 21, 11, 42, 43, 44, - 20, 56, 71, 12, 48, 20, 48, 12, 42, 43, - 44, 45, 48, 80, 48, 45, 12, 15, 48, 12, - 56, 73, 74, 75, 12, 45, 57, 56, 48, 109, - 45, 51, 12, 48, 11, 45, 48, 71, 12, 58, - 68, 71, 59, 138, 14, 79, -1, -1, -1, 79, - 14, 71, -1, -1, -1, -1, 71, -1, 138, 79, - -1, 138, -1, -1, 79, 58, 59, 60, 61, 62, - 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, - 73, 74, 75, 71, 72, 73, 74, 75, 58, 59, - 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, - 70, 71, 72, 73, 74, 75, 31, 71, 72, 73, - 74, 75, 56, -1, 58, 59, 60, 61, 62, 63, - 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, - 74, 75, -1, 58, 59, 60, 61, 62, 63, 64, - 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, - 75, -1, 115, -1, 117, 65, 66, 67, 68, 69, - 70, 71, 72, 73, 74, 75, 129, 130, 131, 132, - 133, 58, 59, 60, 61, 62, 63, 64, 65, 66, - 67, 68, 69, 70, 71, 72, 73, 74, 75, 60, - 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, - 71, 72, 73, 74, 75, 63, 64, 65, 66, 67, - 68, 69, 70, 71, 72, 73, 74, 75, 69, 70, - 71, 72, 73, 74, 75 +static const yytype_int16 yycheck[] = { + 0, 1, 2, 0, 57, 113, 11, 57, 48, 8, + 46, 11, 12, 49, 13, 123, 45, 57, 11, 48, + 11, 13, 11, 76, 77, 71, 72, 73, 74, 75, + 30, 28, 29, 0, 34, 0, 31, 31, 38, 39, + 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, + 50, 51, 52, 53, 54, 55, 45, 11, 108, 59, + 16, 11, 59, 17, 18, 19, 20, 17, 18, 19, + 20, 11, 73, 74, 75, 21, 11, 42, 43, 44, + 20, 56, 71, 12, 48, 20, 48, 12, 42, 43, + 44, 45, 48, 80, 48, 45, 12, 15, 48, 12, + 56, 73, 74, 75, 12, 45, 57, 56, 48, 109, + 45, 51, 12, 48, 11, 45, 48, 71, 12, 58, + 68, 71, 59, 138, 14, 79, -1, -1, -1, 79, + 14, 71, -1, -1, -1, -1, 71, -1, 138, 79, + -1, 138, -1, -1, 79, 58, 59, 60, 61, 62, + 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, + 73, 74, 75, 71, 72, 73, 74, 75, 58, 59, + 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, + 70, 71, 72, 73, 74, 75, 31, 71, 72, 73, + 74, 75, 56, -1, 58, 59, 60, 61, 62, 63, + 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, + 74, 75, -1, 58, 59, 60, 61, 62, 63, 64, + 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, + 75, -1, 115, -1, 117, 65, 66, 67, 68, 69, + 70, 71, 72, 73, 74, 75, 129, 130, 131, 132, + 133, 58, 59, 60, 61, 62, 63, 64, 65, 66, + 67, 68, 69, 70, 71, 72, 73, 74, 75, 60, + 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, + 71, 72, 73, 74, 75, 63, 64, 65, 66, 67, + 68, 69, 70, 71, 72, 73, 74, 75, 69, 70, + 71, 72, 73, 74, 75 }; /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing symbol of state STATE-NUM. */ -static const yytype_uint8 yystos[] = -{ - 0, 11, 17, 18, 19, 20, 42, 43, 44, 45, - 48, 71, 79, 82, 83, 84, 85, 88, 89, 90, - 91, 97, 98, 99, 83, 88, 88, 11, 11, 11, - 13, 88, 88, 0, 57, 76, 77, 86, 58, 59, - 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, - 70, 71, 72, 73, 74, 75, 46, 49, 31, 31, - 12, 21, 45, 83, 83, 88, 51, 88, 80, 87, - 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, - 88, 88, 88, 88, 88, 88, 88, 88, 48, 57, - 92, 93, 94, 92, 91, 88, 97, 56, 102, 12, - 12, 12, 14, 100, 85, 8, 13, 15, 56, 57, - 88, 103, 12, 11, 45, 11, 45, 71, 95, 48, - 96, 92, 88, 56, 101, 103, 95, 95, 14, 71, - 72, 73, 74, 75, 16, 48, 56, 103, 12, 12, - 95, 95, 95, 95, 95, 99 +static const yytype_uint8 yystos[] = { + 0, 11, 17, 18, 19, 20, 42, 43, 44, 45, + 48, 71, 79, 82, 83, 84, 85, 88, 89, 90, + 91, 97, 98, 99, 83, 88, 88, 11, 11, 11, + 13, 88, 88, 0, 57, 76, 77, 86, 58, 59, + 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, + 70, 71, 72, 73, 74, 75, 46, 49, 31, 31, + 12, 21, 45, 83, 83, 88, 51, 88, 80, 87, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 48, 57, + 92, 93, 94, 92, 91, 88, 97, 56, 102, 12, + 12, 12, 14, 100, 85, 8, 13, 15, 56, 57, + 88, 103, 12, 11, 45, 11, 45, 71, 95, 48, + 96, 92, 88, 56, 101, 103, 95, 95, 14, 71, + 72, 73, 74, 75, 16, 48, 56, 103, 12, 12, + 95, 95, 95, 95, 95, 99 }; #define yyerrok (yyerrstatus = 0) @@ -840,10 +823,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) @@ -921,26 +904,26 @@ yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvalue #else static void yy_symbol_value_print (yyoutput, yytype, yyvaluep, ctx, scanner) - FILE *yyoutput; - int yytype; - YYSTYPE const * const yyvaluep; - uscxml::PromelaParser* ctx; - void * scanner; +FILE *yyoutput; +int yytype; +YYSTYPE const * const yyvaluep; +uscxml::PromelaParser* ctx; +void * scanner; #endif { - FILE *yyo = yyoutput; - YYUSE (yyo); - if (!yyvaluep) - return; - YYUSE (ctx); - YYUSE (scanner); + FILE *yyo = yyoutput; + YYUSE (yyo); + if (!yyvaluep) + return; + 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); } @@ -955,20 +938,20 @@ yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, usc #else static void yy_symbol_print (yyoutput, yytype, yyvaluep, ctx, scanner) - FILE *yyoutput; - int yytype; - YYSTYPE const * const yyvaluep; - uscxml::PromelaParser* ctx; - void * scanner; +FILE *yyoutput; +int yytype; +YYSTYPE const * const yyvaluep; +uscxml::PromelaParser* ctx; +void * scanner; #endif { - if (yytype < YYNTOKENS) - YYFPRINTF (yyoutput, "token %s (", yytname[yytype]); - else - YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]); + if (yytype < YYNTOKENS) + YYFPRINTF (yyoutput, "token %s (", yytname[yytype]); + else + YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]); - yy_symbol_value_print (yyoutput, yytype, yyvaluep, ctx, scanner); - YYFPRINTF (yyoutput, ")"); + yy_symbol_value_print (yyoutput, yytype, yyvaluep, ctx, scanner); + YYFPRINTF (yyoutput, ")"); } /*------------------------------------------------------------------. @@ -983,17 +966,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) \ @@ -1014,26 +996,25 @@ yy_reduce_print (YYSTYPE *yyvsp, int yyrule, uscxml::PromelaParser* ctx, void * #else static void yy_reduce_print (yyvsp, yyrule, ctx, scanner) - YYSTYPE *yyvsp; - int yyrule; - uscxml::PromelaParser* ctx; - void * scanner; +YYSTYPE *yyvsp; +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)]) - , 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)]) + , ctx, scanner); + YYFPRINTF (stderr, "\n"); + } } # define YY_REDUCE_PRINT(Rule) \ @@ -1084,13 +1065,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 @@ -1108,17 +1089,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 @@ -1132,42 +1113,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 @@ -1181,133 +1160,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 */ @@ -1323,22 +1292,22 @@ yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep, uscxml::PromelaPar #else static void yydestruct (yymsg, yytype, yyvaluep, ctx, scanner) - const char *yymsg; - int yytype; - YYSTYPE *yyvaluep; - uscxml::PromelaParser* ctx; - void * scanner; +const char *yymsg; +int yytype; +YYSTYPE *yyvaluep; +uscxml::PromelaParser* ctx; +void * scanner; #endif { - YYUSE (yyvaluep); - YYUSE (ctx); - YYUSE (scanner); + YYUSE (yyvaluep); + 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); } @@ -1356,7 +1325,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__ \ @@ -1366,17 +1335,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\"")\ @@ -1384,9 +1353,9 @@ 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 #ifndef YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN @@ -1397,993 +1366,975 @@ static YYSTYPE yyval_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); - /* 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. + /* The stacks and their tools: + `yyss': related to states. + `yyvs': related to semantic values. - 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; - 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; + 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; #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)) - /* 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; - yystacksize = YYINITDEPTH; + yyssp = yyss = yyssa; + yyvsp = yyvs = yyvsa; + 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. */ - goto yysetstate; + yystate = 0; + yyerrstatus = 0; + yynerrs = 0; + yychar = YYEMPTY; /* Cause a token to be read. */ + 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; - - /* 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), - &yystacksize); - - 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; + + /* 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), + &yystacksize); + + 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); + /* 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); # 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; + yyssp = yyss + yysize - 1; + yyvsp = yyvs + 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 - - 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 + + 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]; + /* 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'. + /* 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]; + 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]; - YY_REDUCE_PRINT (yyn); - switch (yyn) - { - case 2: -/* Line 1787 of yacc.c */ + YY_REDUCE_PRINT (yyn); + switch (yyn) { + case 2: + /* Line 1787 of yacc.c */ #line 84 "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 88 "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 92 "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 98 "promela.ypp" - {} - break; + {} + break; - case 6: -/* Line 1787 of yacc.c */ + case 6: + /* Line 1787 of yacc.c */ #line 101 "promela.ypp" - { (yyval.node) = ctx->value(NAME, (yyvsp[(1) - (1)].value)); } - break; + { (yyval.node) = ctx->value(NAME, (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 102 "promela.ypp" - { (yyval.node) = ctx->node(VAR_ARRAY, 2, ctx->value(NAME, (yyvsp[(1) - (4)].value)), (yyvsp[(3) - (4)].node)); } - break; + { (yyval.node) = ctx->node(VAR_ARRAY, 2, ctx->value(NAME, (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 105 "promela.ypp" - {} - break; + {} + break; - case 9: -/* Line 1787 of yacc.c */ + case 9: + /* Line 1787 of yacc.c */ #line 106 "promela.ypp" - {} - break; + {} + break; - case 10: -/* Line 1787 of yacc.c */ + case 10: + /* Line 1787 of yacc.c */ #line 109 "promela.ypp" - {} - break; + {} + break; - case 11: -/* Line 1787 of yacc.c */ + case 11: + /* Line 1787 of yacc.c */ #line 110 "promela.ypp" - {} - break; + {} + break; - case 12: -/* Line 1787 of yacc.c */ + case 12: + /* Line 1787 of yacc.c */ #line 120 "promela.ypp" - { (yyval.node) = (yyvsp[(2) - (3)].node); } - break; + { (yyval.node) = (yyvsp[(2) - (3)].node); } + break; - case 13: -/* Line 1787 of yacc.c */ + case 13: + /* Line 1787 of yacc.c */ #line 121 "promela.ypp" - { (yyval.node) = ctx->node(PLUS, 2, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node)); } - break; + { (yyval.node) = ctx->node(PLUS, 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 122 "promela.ypp" - { (yyval.node) = ctx->node(MINUS, 2, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node)); } - break; + { (yyval.node) = ctx->node(MINUS, 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 123 "promela.ypp" - { (yyval.node) = ctx->node(TIMES, 2, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node)); } - break; + { (yyval.node) = ctx->node(TIMES, 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 124 "promela.ypp" - { (yyval.node) = ctx->node(DIVIDE, 2, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node)); } - break; + { (yyval.node) = ctx->node(DIVIDE, 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 125 "promela.ypp" - { (yyval.node) = ctx->node(MODULO, 2, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node)); } - break; + { (yyval.node) = ctx->node(MODULO, 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 126 "promela.ypp" - { (yyval.node) = ctx->node(BITAND, 2, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node)); } - break; + { (yyval.node) = ctx->node(BITAND, 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 127 "promela.ypp" - { (yyval.node) = ctx->node(BITXOR, 2, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node)); } - break; + { (yyval.node) = ctx->node(BITXOR, 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 128 "promela.ypp" - { (yyval.node) = ctx->node(BITOR, 2, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node)); } - break; + { (yyval.node) = ctx->node(BITOR, 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 129 "promela.ypp" - { (yyval.node) = ctx->node(GT, 2, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node)); } - break; + { (yyval.node) = ctx->node(GT, 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 130 "promela.ypp" - { (yyval.node) = ctx->node(LT, 2, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node)); } - break; + { (yyval.node) = ctx->node(LT, 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 131 "promela.ypp" - { (yyval.node) = ctx->node(GE, 2, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node)); } - break; + { (yyval.node) = ctx->node(GE, 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 132 "promela.ypp" - { (yyval.node) = ctx->node(LE, 2, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node)); } - break; + { (yyval.node) = ctx->node(LE, 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 133 "promela.ypp" - { (yyval.node) = ctx->node(EQ, 2, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node)); } - break; + { (yyval.node) = ctx->node(EQ, 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 134 "promela.ypp" - { (yyval.node) = ctx->node(NE, 2, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node)); } - break; + { (yyval.node) = ctx->node(NE, 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 135 "promela.ypp" - { (yyval.node) = ctx->node(AND, 2, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node)); } - break; + { (yyval.node) = ctx->node(AND, 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 136 "promela.ypp" - { (yyval.node) = ctx->node(OR, 2, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node)); } - break; + { (yyval.node) = ctx->node(OR, 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 137 "promela.ypp" - { (yyval.node) = ctx->node(LSHIFT, 2, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node)); } - break; + { (yyval.node) = ctx->node(LSHIFT, 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 138 "promela.ypp" - { (yyval.node) = ctx->node(RSHIFT, 2, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node)); } - break; + { (yyval.node) = ctx->node(RSHIFT, 2, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node)); } + break; - case 31: -/* Line 1787 of yacc.c */ + case 31: + /* Line 1787 of yacc.c */ #line 139 "promela.ypp" - { (yyval.node) = ctx->node(NEG, 1, (yyvsp[(2) - (2)].node)); } - break; + { (yyval.node) = ctx->node(NEG, 1, (yyvsp[(2) - (2)].node)); } + break; - case 32: -/* Line 1787 of yacc.c */ + case 32: + /* Line 1787 of yacc.c */ #line 140 "promela.ypp" - { (yyval.node) = ctx->node(MINUS, 1, (yyvsp[(2) - (2)].node)); } - break; + { (yyval.node) = ctx->node(MINUS, 1, (yyvsp[(2) - (2)].node)); } + break; - case 33: -/* Line 1787 of yacc.c */ + case 33: + /* Line 1787 of yacc.c */ #line 142 "promela.ypp" - { (yyval.node) = ctx->node(LEN, 1, (yyvsp[(3) - (4)].node)); } - break; + { (yyval.node) = ctx->node(LEN, 1, (yyvsp[(3) - (4)].node)); } + break; - case 34: -/* Line 1787 of yacc.c */ + case 34: + /* Line 1787 of yacc.c */ #line 143 "promela.ypp" - { } - break; + { } + break; - case 35: -/* Line 1787 of yacc.c */ + case 35: + /* Line 1787 of yacc.c */ #line 144 "promela.ypp" - { (yyval.node) = ctx->value(CONST, yylval.value); } - break; + { (yyval.node) = ctx->value(CONST, (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 148 "promela.ypp" - { (yyval.node) = ctx->node(SHOW, 0); } - break; + { (yyval.node) = ctx->node(SHOW, 0); } + break; - case 37: -/* Line 1787 of yacc.c */ + case 37: + /* Line 1787 of yacc.c */ #line 149 "promela.ypp" - { (yyval.node) = ctx->node(HIDDEN, 0); } - break; + { (yyval.node) = ctx->node(HIDDEN, 0); } + break; - case 38: -/* Line 1787 of yacc.c */ + case 38: + /* Line 1787 of yacc.c */ #line 150 "promela.ypp" - { (yyval.node) = ctx->node(SHOW, 0); } - break; + { (yyval.node) = ctx->node(SHOW, 0); } + break; - case 39: -/* Line 1787 of yacc.c */ + case 39: + /* Line 1787 of yacc.c */ #line 151 "promela.ypp" - { (yyval.node) = ctx->node(ISLOCAL, 0); } - break; + { (yyval.node) = ctx->node(ISLOCAL, 0); } + break; - case 40: -/* Line 1787 of yacc.c */ + case 40: + /* Line 1787 of yacc.c */ #line 154 "promela.ypp" - { (yyval.node) = ctx->node(DECL, 3, (yyvsp[(1) - (3)].node), ctx->value(TYPE, (yyvsp[(2) - (3)].value)), (yyvsp[(3) - (3)].node)); } - break; + { (yyval.node) = ctx->node(DECL, 3, (yyvsp[(1) - (3)].node), ctx->value(TYPE, (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 155 "promela.ypp" - { (yyval.node) = ctx->node(UNAME, 2, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node)); } - break; + { (yyval.node) = ctx->node(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 156 "promela.ypp" - { (yyval.node) = ctx->node(DECL, 3, (yyvsp[(1) - (6)].node), ctx->value(TYPE, (yyvsp[(2) - (6)].value)), (yyvsp[(5) - (6)].node)); } - break; + { (yyval.node) = ctx->node(DECL, 3, (yyvsp[(1) - (6)].node), ctx->value(TYPE, (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 159 "promela.ypp" - { (yyval.node) = (yyvsp[(1) - (1)].node); } - break; + { (yyval.node) = (yyvsp[(1) - (1)].node); } + break; - case 44: -/* Line 1787 of yacc.c */ + case 44: + /* Line 1787 of yacc.c */ #line 160 "promela.ypp" - { (yyval.node) = (yyvsp[(1) - (2)].node); } - break; + { (yyval.node) = (yyvsp[(1) - (2)].node); } + break; - case 45: -/* Line 1787 of yacc.c */ + case 45: + /* Line 1787 of yacc.c */ #line 161 "promela.ypp" - { - (yyval.node) = ctx->node(DECLLIST, 1, (yyvsp[(1) - (3)].node)); - if((yyvsp[(3) - (3)].node)->type == DECLLIST) { - (yyval.node)->merge((yyvsp[(3) - (3)].node)); delete (yyvsp[(3) - (3)].node); - } else { - (yyval.node)->push((yyvsp[(3) - (3)].node)); - } - } - break; - - case 46: -/* Line 1787 of yacc.c */ + { + (yyval.node) = ctx->node(DECLLIST, 1, (yyvsp[(1) - (3)].node)); + if((yyvsp[(3) - (3)].node)->type == DECLLIST) { + (yyval.node)->merge((yyvsp[(3) - (3)].node)); + delete (yyvsp[(3) - (3)].node); + } else { + (yyval.node)->push((yyvsp[(3) - (3)].node)); + } + } + break; + + case 46: + /* Line 1787 of yacc.c */ #line 171 "promela.ypp" - { (yyval.node) = ctx->node(VARLIST, 1, (yyvsp[(1) - (1)].node)); } - break; + { (yyval.node) = ctx->node(VARLIST, 1, (yyvsp[(1) - (1)].node)); } + break; - case 47: -/* Line 1787 of yacc.c */ + case 47: + /* Line 1787 of yacc.c */ #line 172 "promela.ypp" - { (yyval.node) = ctx->node(VARLIST, 1, (yyvsp[(1) - (3)].node)); (yyval.node)->merge((yyvsp[(3) - (3)].node)); delete (yyvsp[(3) - (3)].node); } - break; + { (yyval.node) = ctx->node(VARLIST, 1, (yyvsp[(1) - (3)].node)); (yyval.node)->merge((yyvsp[(3) - (3)].node)); delete (yyvsp[(3) - (3)].node); } + break; - case 48: -/* Line 1787 of yacc.c */ + case 48: + /* Line 1787 of yacc.c */ #line 175 "promela.ypp" - { (yyval.node) = (yyvsp[(1) - (1)].node); } - break; + { (yyval.node) = (yyvsp[(1) - (1)].node); } + break; - case 49: -/* Line 1787 of yacc.c */ + case 49: + /* Line 1787 of yacc.c */ #line 176 "promela.ypp" - { (yyval.node) = ctx->node(ASGN, 2, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node)); } - break; + { (yyval.node) = ctx->node(ASGN, 2, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node)); } + break; - case 50: -/* Line 1787 of yacc.c */ + case 50: + /* Line 1787 of yacc.c */ #line 179 "promela.ypp" - { (yyval.node) = ctx->value(NAME, (yyvsp[(1) - (1)].value)); } - break; + { (yyval.node) = ctx->value(NAME, (yyvsp[(1) - (1)].value)); free((yyvsp[(1) - (1)].value)); } + break; - case 51: -/* Line 1787 of yacc.c */ + case 51: + /* Line 1787 of yacc.c */ #line 180 "promela.ypp" - { (yyval.node) = ctx->node(COLON, 2, ctx->value(NAME, (yyvsp[(1) - (3)].value)), ctx->value(CONST, (yyvsp[(3) - (3)].value))); } - break; + { (yyval.node) = ctx->node(COLON, 2, ctx->value(NAME, (yyvsp[(1) - (3)].value)), ctx->value(CONST, (yyvsp[(3) - (3)].value))); free((yyvsp[(1) - (3)].value)); free((yyvsp[(3) - (3)].value)); } + break; - case 52: -/* Line 1787 of yacc.c */ + case 52: + /* Line 1787 of yacc.c */ #line 181 "promela.ypp" - { (yyval.node) = ctx->node(VAR_ARRAY, 2, ctx->value(NAME, (yyvsp[(1) - (4)].value)), (yyvsp[(3) - (4)].node)); } - break; + { (yyval.node) = ctx->node(VAR_ARRAY, 2, ctx->value(NAME, (yyvsp[(1) - (4)].value)), (yyvsp[(3) - (4)].node)); free((yyvsp[(1) - (4)].value)); } + break; - case 53: -/* Line 1787 of yacc.c */ + case 53: + /* Line 1787 of yacc.c */ #line 184 "promela.ypp" - { (yyval.node) = ctx->value(CONST, yylval.value); } - break; + { (yyval.node) = ctx->value(CONST, (yyvsp[(1) - (1)].value)); free((yyvsp[(1) - (1)].value)); } + break; - case 54: -/* Line 1787 of yacc.c */ + case 54: + /* Line 1787 of yacc.c */ #line 185 "promela.ypp" - { (yyval.node) = ctx->node(MINUS, 1, (yyvsp[(2) - (2)].node)); } - break; + { (yyval.node) = ctx->node(MINUS, 1, (yyvsp[(2) - (2)].node)); } + break; - case 55: -/* Line 1787 of yacc.c */ + case 55: + /* Line 1787 of yacc.c */ #line 186 "promela.ypp" - { (yyval.node) = (yyvsp[(2) - (3)].node); } - break; + { (yyval.node) = (yyvsp[(2) - (3)].node); } + break; - case 56: -/* Line 1787 of yacc.c */ + case 56: + /* Line 1787 of yacc.c */ #line 187 "promela.ypp" - { (yyval.node) = ctx->node(PLUS, 2, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node)); } - break; + { (yyval.node) = ctx->node(PLUS, 2, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node)); } + break; - case 57: -/* Line 1787 of yacc.c */ + case 57: + /* Line 1787 of yacc.c */ #line 188 "promela.ypp" - { (yyval.node) = ctx->node(MINUS, 2, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node)); } - break; + { (yyval.node) = ctx->node(MINUS, 2, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node)); } + break; - case 58: -/* Line 1787 of yacc.c */ + case 58: + /* Line 1787 of yacc.c */ #line 189 "promela.ypp" - { (yyval.node) = ctx->node(TIMES, 2, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node)); } - break; + { (yyval.node) = ctx->node(TIMES, 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 190 "promela.ypp" - { (yyval.node) = ctx->node(DIVIDE, 2, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node)); } - break; + { (yyval.node) = ctx->node(DIVIDE, 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 191 "promela.ypp" - { (yyval.node) = ctx->node(MODULO, 2, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node)); } - break; + { (yyval.node) = ctx->node(MODULO, 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 194 "promela.ypp" - { (yyval.node) = ctx->value(NAME, (yyvsp[(1) - (1)].value)); } - break; + { (yyval.node) = ctx->value(NAME, (yyvsp[(1) - (1)].value)); free((yyvsp[(1) - (1)].value)); } + break; - case 62: -/* Line 1787 of yacc.c */ + case 62: + /* Line 1787 of yacc.c */ #line 195 "promela.ypp" - { - if ((yyvsp[(1) - (2)].node)->type == NAME) { - (yyval.node) = ctx->node(NAMELIST, 1, (yyvsp[(1) - (2)].node)); - (yyval.node)->push(ctx->value(NAME, (yyvsp[(2) - (2)].value))); - } else { - (yyvsp[(1) - (2)].node)->push(ctx->value(NAME, (yyvsp[(2) - (2)].value))); - } - } - break; - - case 63: -/* Line 1787 of yacc.c */ -#line 203 "promela.ypp" - { (yyval.node) = (yyvsp[(1) - (2)].node); } - break; - - case 64: -/* Line 1787 of yacc.c */ -#line 206 "promela.ypp" - { (yyval.node) = (yyvsp[(1) - (1)].node); } - break; - - case 65: -/* Line 1787 of yacc.c */ + { + if ((yyvsp[(1) - (2)].node)->type == NAME) { + (yyval.node) = ctx->node(NAMELIST, 1, (yyvsp[(1) - (2)].node)); + (yyval.node)->push(ctx->value(NAME, (yyvsp[(2) - (2)].value))); + } else { + (yyvsp[(1) - (2)].node)->push(ctx->value(NAME, (yyvsp[(2) - (2)].value))); + } + free((yyvsp[(2) - (2)].value)); + } + break; + + case 63: + /* Line 1787 of yacc.c */ +#line 204 "promela.ypp" + { (yyval.node) = (yyvsp[(1) - (2)].node); } + break; + + case 64: + /* Line 1787 of yacc.c */ #line 207 "promela.ypp" - { (yyval.node) = (yyvsp[(1) - (2)].node); } - break; + { (yyval.node) = (yyvsp[(1) - (1)].node); } + break; - case 66: -/* Line 1787 of yacc.c */ + case 65: + /* Line 1787 of yacc.c */ #line 208 "promela.ypp" - { (yyval.node) = ctx->node(STMNT, 2, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node)); } - break; - - case 67: -/* Line 1787 of yacc.c */ -#line 211 "promela.ypp" - { (yyval.node) = (yyvsp[(1) - (1)].node); } - break; - - case 68: -/* Line 1787 of yacc.c */ -#line 214 "promela.ypp" - { (yyval.node) = ctx->node(ASGN, 2, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node)); } - break; - - case 69: -/* Line 1787 of yacc.c */ + { (yyval.node) = (yyvsp[(1) - (2)].node); } + break; + + case 66: + /* Line 1787 of yacc.c */ +#line 209 "promela.ypp" + { (yyval.node) = ctx->node(STMNT, 2, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node)); } + break; + + case 67: + /* Line 1787 of yacc.c */ +#line 212 "promela.ypp" + { (yyval.node) = (yyvsp[(1) - (1)].node); } + break; + + case 68: + /* Line 1787 of yacc.c */ #line 215 "promela.ypp" - { (yyval.node) = ctx->node(INCR, 1, (yyvsp[(1) - (2)].node)); } - break; + { (yyval.node) = ctx->node(ASGN, 2, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node)); } + break; - case 70: -/* Line 1787 of yacc.c */ + case 69: + /* Line 1787 of yacc.c */ #line 216 "promela.ypp" - { (yyval.node) = ctx->node(DECR, 1, (yyvsp[(1) - (2)].node)); } - break; + { (yyval.node) = ctx->node(INCR, 1, (yyvsp[(1) - (2)].node)); } + break; - case 71: -/* Line 1787 of yacc.c */ + case 70: + /* Line 1787 of yacc.c */ #line 217 "promela.ypp" - { (yyval.node) = ctx->node(PRINT, 2, ctx->value(STRING, (yyvsp[(3) - (5)].value)), (yyvsp[(4) - (5)].node)); } - break; + { (yyval.node) = ctx->node(DECR, 1, (yyvsp[(1) - (2)].node)); } + break; - case 72: -/* Line 1787 of yacc.c */ + case 71: + /* Line 1787 of yacc.c */ #line 218 "promela.ypp" - { (yyval.node) = ctx->node(PRINTM, 1, (yyvsp[(3) - (4)].node)); } - break; + { (yyval.node) = ctx->node(PRINT, 2, ctx->value(STRING, (yyvsp[(3) - (5)].value)), (yyvsp[(4) - (5)].node)); free((yyvsp[(3) - (5)].value)); } + break; - case 73: -/* Line 1787 of yacc.c */ + case 72: + /* Line 1787 of yacc.c */ #line 219 "promela.ypp" - { (yyval.node) = ctx->node(PRINTM, 1, ctx->value(CONST, (yyvsp[(3) - (4)].value))); } - break; + { (yyval.node) = ctx->node(PRINTM, 1, (yyvsp[(3) - (4)].node)); } + break; - case 74: -/* Line 1787 of yacc.c */ + case 73: + /* Line 1787 of yacc.c */ #line 220 "promela.ypp" - { } - break; + { (yyval.node) = ctx->node(PRINTM, 1, ctx->value(CONST, (yyvsp[(3) - (4)].value))); free((yyvsp[(3) - (4)].value)); } + break; - case 75: -/* Line 1787 of yacc.c */ + case 74: + /* Line 1787 of yacc.c */ #line 221 "promela.ypp" - { (yyval.node) = (yyvsp[(1) - (1)].node); } - break; - - case 76: -/* Line 1787 of yacc.c */ -#line 222 "promela.ypp" - { } - break; + { } + break; - case 77: -/* Line 1787 of yacc.c */ + case 75: + /* Line 1787 of yacc.c */ #line 222 "promela.ypp" - { } - break; - - case 78: -/* Line 1787 of yacc.c */ -#line 225 "promela.ypp" - { } - break; - - case 79: -/* Line 1787 of yacc.c */ + { (yyval.node) = (yyvsp[(1) - (1)].node); } + break; + + case 76: + /* Line 1787 of yacc.c */ +#line 223 "promela.ypp" + { } + break; + + case 77: + /* Line 1787 of yacc.c */ +#line 223 "promela.ypp" + { } + break; + + case 78: + /* Line 1787 of yacc.c */ #line 226 "promela.ypp" - { } - break; + { } + break; - case 80: -/* Line 1787 of yacc.c */ -#line 229 "promela.ypp" - { (yyval.node) = ctx->value(0, ""); } - break; + case 79: + /* Line 1787 of yacc.c */ +#line 227 "promela.ypp" + { } + break; - case 81: -/* Line 1787 of yacc.c */ + case 80: + /* Line 1787 of yacc.c */ #line 230 "promela.ypp" - { (yyval.node) = (yyvsp[(2) - (2)].node); } - break; + { (yyval.node) = ctx->value(0, ""); } + break; - case 82: -/* Line 1787 of yacc.c */ -#line 233 "promela.ypp" - { (yyval.node) = (yyvsp[(1) - (1)].node); } - break; + case 81: + /* Line 1787 of yacc.c */ +#line 231 "promela.ypp" + { (yyval.node) = (yyvsp[(2) - (2)].node); } + break; - case 83: -/* Line 1787 of yacc.c */ + case 82: + /* Line 1787 of yacc.c */ #line 234 "promela.ypp" - { (yyval.node) = ctx->node(0, 2, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node)); } - break; - - -/* Line 1787 of yacc.c */ -#line 2156 "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; - - /* 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 | -`------------------------------------*/ + { (yyval.node) = (yyvsp[(1) - (1)].node); } + break; + + case 83: + /* Line 1787 of yacc.c */ +#line 235 "promela.ypp" + { (yyval.node) = ctx->node(0, 2, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node)); } + break; + + + /* Line 1787 of yacc.c */ +#line 2157 "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; + + /* 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 (ctx, scanner, YY_("syntax error")); + yyerror (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 (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 (ctx, scanner, yymsgp); + if (yysyntax_error_status == 2) + goto yyexhaustedlab; + } # undef YYSYNTAX_ERROR #endif - } + } - if (yyerrstatus == 3) - { - /* If just tried and failed to reuse lookahead token after an - error, discard it. */ + 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, ctx, scanner); - yychar = YYEMPTY; + if (yychar <= YYEOF) { + /* Return failure if at end of input. */ + if (yychar == YYEOF) + YYABORT; + } else { + yydestruct ("Error: discarding", + yytoken, &yylval, 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; + /* 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; - /* 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; + /* 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 -- 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; + + + yydestruct ("Error: popping", + yystos[yystate], yyvsp, 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; + YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN + *++yyvsp = yylval; + YY_IGNORE_MAYBE_UNINITIALIZED_END - yydestruct ("Error: popping", - yystos[yystate], yyvsp, ctx, scanner); - YYPOPSTACK (1); - yystate = *yyssp; - YY_STACK_PRINT (yyss, yyssp); - } + /* Shift the error token. */ + YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp); - YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN - *++yyvsp = yylval; - YY_IGNORE_MAYBE_UNINITIALIZED_END + yystate = yyn; + goto yynewstate; - /* Shift the error token. */ - YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp); - - 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 (ctx, scanner, YY_("memory exhausted")); - yyresult = 2; - /* Fall through. */ + yyerror (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, 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, 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, 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, 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); } /* Line 2050 of yacc.c */ -#line 238 "promela.ypp" +#line 239 "promela.ypp" diff --git a/src/uscxml/plugins/datamodel/promela/parser/promela.ypp b/src/uscxml/plugins/datamodel/promela/parser/promela.ypp index b33ebd1..5d45c71 100644 --- a/src/uscxml/plugins/datamodel/promela/parser/promela.ypp +++ b/src/uscxml/plugins/datamodel/promela/parser/promela.ypp @@ -98,8 +98,8 @@ program : varref : cmpnd {} ; -pfld : NAME { $$ = ctx->value(NAME, $1); } - | NAME '[' expr ']' { $$ = ctx->node(VAR_ARRAY, 2, ctx->value(NAME, $1), $3); } +pfld : NAME { $$ = ctx->value(NAME, $1); free($1); } + | NAME '[' expr ']' { $$ = ctx->node(VAR_ARRAY, 2, ctx->value(NAME, $1), $3); free($1); } ; cmpnd : pfld {} @@ -141,7 +141,7 @@ expr : '(' expr ')' { $$ = $2; } | LEN '(' varref ')' { $$ = ctx->node(LEN, 1, $3); } | varref { } - | CONST { $$ = ctx->value(CONST, yylval.value); } + | CONST { $$ = ctx->value(CONST, $1); free($1); } ; @@ -151,9 +151,9 @@ vis : /* empty */ { $$ = ctx->node(SHOW, 0); } | ISLOCAL { $$ = ctx->node(ISLOCAL, 0); } ; -one_decl: vis TYPE var_list { $$ = ctx->node(DECL, 3, $1, ctx->value(TYPE, $2), $3); } +one_decl: vis TYPE var_list { $$ = ctx->node(DECL, 3, $1, ctx->value(TYPE, $2), $3); free($2); } | vis UNAME var_list { $$ = ctx->node(UNAME, 2, $1, $3); } - | vis TYPE ASGN '{' nlst '}' { $$ = ctx->node(DECL, 3, $1, ctx->value(TYPE, $2), $5); } + | vis TYPE ASGN '{' nlst '}' { $$ = ctx->node(DECL, 3, $1, ctx->value(TYPE, $2), $5); free($2); } ; decl_lst: one_decl { $$ = $1; } @@ -176,12 +176,12 @@ ivar : vardcl { $$ = $1; } | vardcl ASGN expr { $$ = ctx->node(ASGN, 2, $1, $3); } ; -vardcl : NAME { $$ = ctx->value(NAME, $1); } - | NAME COLON CONST { $$ = ctx->node(COLON, 2, ctx->value(NAME, $1), ctx->value(CONST, $3)); } - | NAME '[' const_expr ']' { $$ = ctx->node(VAR_ARRAY, 2, ctx->value(NAME, $1), $3); } +vardcl : NAME { $$ = ctx->value(NAME, $1); free($1); } + | NAME COLON CONST { $$ = ctx->node(COLON, 2, ctx->value(NAME, $1), ctx->value(CONST, $3)); free($1); free($3); } + | NAME '[' const_expr ']' { $$ = ctx->node(VAR_ARRAY, 2, ctx->value(NAME, $1), $3); free($1); } ; -const_expr: CONST { $$ = ctx->value(CONST, yylval.value); } +const_expr: CONST { $$ = ctx->value(CONST, $1); free($1); } | MINUS const_expr %prec MINUS { $$ = ctx->node(MINUS, 1, $2); } | '(' const_expr ')' { $$ = $2; } | const_expr PLUS const_expr { $$ = ctx->node(PLUS, 2, $1, $3); } @@ -191,7 +191,7 @@ const_expr: CONST { $$ = ctx->value(CONST, yylval.value); } | const_expr MODULO const_expr { $$ = ctx->node(MODULO, 2, $1, $3); } ; -nlst : NAME { $$ = ctx->value(NAME, $1); } +nlst : NAME { $$ = ctx->value(NAME, $1); free($1); } | nlst NAME { if ($1->type == NAME) { $$ = ctx->node(NAMELIST, 1, $1); @@ -199,6 +199,7 @@ nlst : NAME { $$ = ctx->value(NAME, $1); } } else { $1->push(ctx->value(NAME, $2)); } + free($2); } | nlst COMMA { $$ = $1; } ; @@ -214,9 +215,9 @@ stmnt : Stmnt { $$ = $1; } Stmnt : varref ASGN expr { $$ = ctx->node(ASGN, 2, $1, $3); } | varref INCR { $$ = ctx->node(INCR, 1, $1); } | varref DECR { $$ = ctx->node(DECR, 1, $1); } - | PRINT '(' STRING prargs ')' { $$ = ctx->node(PRINT, 2, ctx->value(STRING, $3), $4); } + | PRINT '(' STRING prargs ')' { $$ = ctx->node(PRINT, 2, ctx->value(STRING, $3), $4); free($3); } | PRINTM '(' varref ')' { $$ = ctx->node(PRINTM, 1, $3); } - | PRINTM '(' CONST ')' { $$ = ctx->node(PRINTM, 1, ctx->value(CONST, $3)); } + | PRINTM '(' CONST ')' { $$ = ctx->node(PRINTM, 1, ctx->value(CONST, $3)); free($3); } | ASSERT expr { } | expr { $$ = $1; } | varref ASGN INAME { } '(' args ')' Stmnt { } diff --git a/src/uscxml/plugins/datamodel/xpath/XPathDataModel.cpp b/src/uscxml/plugins/datamodel/xpath/XPathDataModel.cpp index 27bf170..c3e82df 100644 --- a/src/uscxml/plugins/datamodel/xpath/XPathDataModel.cpp +++ b/src/uscxml/plugins/datamodel/xpath/XPathDataModel.cpp @@ -54,7 +54,7 @@ boost::shared_ptr<DataModelImpl> XPathDataModel::create(InterpreterImpl* interpr // dm->_xpath->setNamespaceContext(interpreter->getNSContext()); dm->_funcResolver.setInterpreter(interpreter); - dm->_xpath.setNamespaceContext(interpreter->getNSContext()); + dm->_xpath.setNamespaceContext(*interpreter->getNameSpaceInfo().nsContext); dm->_xpath.setFunctionResolver(dm->_funcResolver); dm->_xpath.setVariableResolver(dm->_varResolver); @@ -860,7 +860,7 @@ bool XPathFunctionIn::doEvaluate(const Node<std::string>& context, continue; } } - return false; + return false; } return true; } diff --git a/src/uscxml/plugins/invoker/im/IMInvoker.cpp b/src/uscxml/plugins/invoker/im/IMInvoker.cpp index 6de4063..d086a20 100644 --- a/src/uscxml/plugins/invoker/im/IMInvoker.cpp +++ b/src/uscxml/plugins/invoker/im/IMInvoker.cpp @@ -721,7 +721,7 @@ void IMInvoker::send(void *userdata, const std::string event) { if (ctx->sendReq.content.length() > 0) purple_conv_im_send(purple_conversation_get_im_data(conv), ctx->sendReq.content.c_str()); #endif - + #if 0 if (data.binary) { PurpleConnection *gc = purple_account_get_connection(ctx->instance->_account); @@ -770,7 +770,7 @@ void IMInvoker::send(void *userdata, const std::string event) { #else purple_account_add_buddy(ctx->instance->_account, buddy); #endif - + } else if (iequals(ctx->sendReq.name, "im.buddy.remove")) { std::string buddyName; Event::getParam(ctx->sendReq.params, "name", buddyName); diff --git a/src/uscxml/plugins/invoker/imap/IMAPInvoker.cpp b/src/uscxml/plugins/invoker/imap/IMAPInvoker.cpp index 5237977..d3686f9 100644 --- a/src/uscxml/plugins/invoker/imap/IMAPInvoker.cpp +++ b/src/uscxml/plugins/invoker/imap/IMAPInvoker.cpp @@ -84,22 +84,22 @@ size_t IMAPInvoker::writeCurlData(void *ptr, size_t size, size_t nmemb, void *us size_t IMAPInvoker::readCurlData(void *ptr, size_t size, size_t nmemb, void *userdata) { if (!userdata) return 0; - + IMAPContext* ctx = (IMAPContext*)userdata; ctx->inContent << std::string((char*)ptr, size * nmemb); - + return size * nmemb; } - + void IMAPInvoker::send(const SendRequest& req) { IMAPContext* ctx = NULL; - + if (false) { } else if (iequals(req.name, "select")) { IMAPContext::Select* args = new IMAPContext::Select(); Event::getParam(req.params, "mailbox", args->mailbox); - + ctx = new IMAPContext(); ctx->command = IMAPContext::IMAP_SELECT; ctx->arguments = args; @@ -107,7 +107,7 @@ void IMAPInvoker::send(const SendRequest& req) { } else if (iequals(req.name, "examine")) { IMAPContext::Examine* args = new IMAPContext::Examine(); Event::getParam(req.params, "mailbox", args->mailbox); - + ctx = new IMAPContext(); ctx->command = IMAPContext::IMAP_EXAMINE; ctx->arguments = args; @@ -115,7 +115,7 @@ void IMAPInvoker::send(const SendRequest& req) { } else if (iequals(req.name, "delete")) { IMAPContext::Delete* args = new IMAPContext::Delete(); Event::getParam(req.params, "mailbox", args->mailbox); - + ctx = new IMAPContext(); ctx->command = IMAPContext::IMAP_DELETE; ctx->arguments = args; @@ -124,7 +124,7 @@ void IMAPInvoker::send(const SendRequest& req) { IMAPContext::Rename* args = new IMAPContext::Rename(); Event::getParam(req.params, "mailbox", args->mailbox); Event::getParam(req.params, "name", args->newName); - + ctx = new IMAPContext(); ctx->command = IMAPContext::IMAP_RENAME; ctx->arguments = args; @@ -132,7 +132,7 @@ void IMAPInvoker::send(const SendRequest& req) { } else if (iequals(req.name, "subscribe")) { IMAPContext::Subscribe* args = new IMAPContext::Subscribe(); Event::getParam(req.params, "mailbox", args->mailbox); - + ctx = new IMAPContext(); ctx->command = IMAPContext::IMAP_SUBSCRIBE; ctx->arguments = args; @@ -140,7 +140,7 @@ void IMAPInvoker::send(const SendRequest& req) { } else if (iequals(req.name, "unsubscribe")) { IMAPContext::Unsubscribe* args = new IMAPContext::Unsubscribe(); Event::getParam(req.params, "mailbox", args->mailbox); - + ctx = new IMAPContext(); ctx->command = IMAPContext::IMAP_UNSUBSCRIBE; ctx->arguments = args; @@ -149,7 +149,7 @@ void IMAPInvoker::send(const SendRequest& req) { IMAPContext::List* args = new IMAPContext::List(); Event::getParam(req.params, "mailbox", args->mailbox); Event::getParam(req.params, "reference", args->refName); - + ctx = new IMAPContext(); ctx->command = IMAPContext::IMAP_LIST; ctx->arguments = args; @@ -158,7 +158,7 @@ void IMAPInvoker::send(const SendRequest& req) { IMAPContext::LSub* args = new IMAPContext::LSub(); Event::getParam(req.params, "mailbox", args->mailbox); Event::getParam(req.params, "reference", args->refName); - + ctx = new IMAPContext(); ctx->command = IMAPContext::IMAP_LSUB; ctx->arguments = args; @@ -167,7 +167,7 @@ void IMAPInvoker::send(const SendRequest& req) { IMAPContext::Status* args = new IMAPContext::Status(); Event::getParam(req.params, "mailbox", args->mailbox); Event::getParam(req.params, "dataitems", args->dataItems); - + ctx = new IMAPContext(); ctx->command = IMAPContext::IMAP_STATUS; ctx->arguments = args; @@ -181,107 +181,107 @@ void IMAPInvoker::send(const SendRequest& req) { if (!Event::getParam(req.params, "message", args->literal)) { args->literal = req.content; } - + ctx = new IMAPContext(); ctx->command = IMAPContext::IMAP_APPEND; ctx->arguments = args; } else if (iequals(req.name, "check")) { IMAPContext::Check* args = new IMAPContext::Check(); - + ctx = new IMAPContext(); ctx->command = IMAPContext::IMAP_CHECK; ctx->arguments = args; } else if (iequals(req.name, "close")) { IMAPContext::Close* args = new IMAPContext::Close(); - + ctx = new IMAPContext(); ctx->command = IMAPContext::IMAP_CLOSE; ctx->arguments = args; - + } else if (iequals(req.name, "expunge")) { IMAPContext::Expunge* args = new IMAPContext::Expunge(); - + ctx = new IMAPContext(); ctx->command = IMAPContext::IMAP_EXPUNGE; ctx->arguments = args; - + } else if (iequals(req.name, "search")) { IMAPContext::Search* args = new IMAPContext::Search(); Event::getParam(req.params, "charset", args->charSet); Event::getParam(req.params, "criteria", args->criteria); - + ctx = new IMAPContext(); ctx->command = IMAPContext::IMAP_SEARCH; ctx->arguments = args; - + } else if (iequals(req.name, "fetch")) { IMAPContext::Fetch* args = new IMAPContext::Fetch(); Event::getParam(req.params, "sequence", args->sequence); Event::getParam(req.params, "itemnames", args->itemNames); - + ctx = new IMAPContext(); ctx->command = IMAPContext::IMAP_FETCH; ctx->arguments = args; - + } else if (iequals(req.name, "store")) { IMAPContext::Store* args = new IMAPContext::Store(); Event::getParam(req.params, "sequence", args->sequence); Event::getParam(req.params, "itemnames", args->itemNames); Event::getParam(req.params, "values", args->values); - + ctx = new IMAPContext(); ctx->command = IMAPContext::IMAP_STORE; ctx->arguments = args; - + } else if (iequals(req.name, "copy")) { IMAPContext::Copy* args = new IMAPContext::Copy(); Event::getParam(req.params, "mailbox", args->mailbox); Event::getParam(req.params, "sequence", args->sequence); - + ctx = new IMAPContext(); ctx->command = IMAPContext::IMAP_COPY; ctx->arguments = args; - + } else if (iequals(req.name, "uid")) { IMAPContext::UId* args = new IMAPContext::UId(); Event::getParam(req.params, "command", args->command); Event::getParam(req.params, "arguments", args->arguments); - + ctx = new IMAPContext(); ctx->command = IMAPContext::IMAP_UID; ctx->arguments = args; - + } else if (boost::istarts_with(req.name, "x")) { IMAPContext::XExtension* args = new IMAPContext::XExtension(); args->command = req.name; Event::getParam(req.params, "arguments", args->arguments); - + ctx = new IMAPContext(); ctx->command = IMAPContext::IMAP_XEXTENSION; ctx->arguments = args; - + } - + if (ctx == NULL) { returnErrorExecution("Event '" + req.name + "' not known"); return; } - + Event::getParam(req.params, "verbose", ctx->verbose); Event::getParam(req.params, "ssl", ctx->useSSL); ctx->invoker = this; ctx->sendReq = req; - + _workQueue.push(ctx); } void IMAPInvoker::process(IMAPContext* ctx) { CURL* _curl; CURLcode curlError; - + // see http://curl.haxx.se/libcurl/c/imap-tls.html _curl = curl_easy_init(); if(_curl) { @@ -291,7 +291,7 @@ void IMAPInvoker::process(IMAPContext* ctx) { LOG(ERROR) << "Cannot set password: " << curl_easy_strerror(curlError); (curlError = curl_easy_setopt(_curl, CURLOPT_URL, _server.c_str())) == CURLE_OK || LOG(ERROR) << "Cannot set server string: " << curl_easy_strerror(curlError); - + if (ctx->useSSL) { (curlError = curl_easy_setopt(_curl, CURLOPT_USE_SSL, (long)CURLUSESSL_ALL)) == CURLE_OK || LOG(ERROR) << "Cannot use SSL: " << curl_easy_strerror(curlError); @@ -304,9 +304,9 @@ void IMAPInvoker::process(IMAPContext* ctx) { (curlError = curl_easy_setopt(_curl, CURLOPT_CAINFO, "/path/to/certificate.pem")) == CURLE_OK || LOG(ERROR) << "Cannot set CA info path: " << curl_easy_strerror(curlError); #endif - + } - + (curlError = curl_easy_setopt(_curl, CURLOPT_READFUNCTION, IMAPInvoker::writeCurlData)) == CURLE_OK || LOG(ERROR) << "Cannot register read function: " << curl_easy_strerror(curlError); (curlError = curl_easy_setopt(_curl, CURLOPT_READDATA, ctx)) == CURLE_OK || @@ -315,7 +315,7 @@ void IMAPInvoker::process(IMAPContext* ctx) { LOG(ERROR) << "Cannot register read function: " << curl_easy_strerror(curlError); (curlError = curl_easy_setopt(_curl, CURLOPT_WRITEDATA, ctx)) == CURLE_OK || LOG(ERROR) << "Cannot register userdata for write function: " << curl_easy_strerror(curlError); - + if (ctx->verbose) { (curlError = curl_easy_setopt(_curl, CURLOPT_VERBOSE, 1L)) == CURLE_OK || LOG(ERROR) << "Cannot set curl to verbose: " << curl_easy_strerror(curlError); @@ -323,114 +323,114 @@ void IMAPInvoker::process(IMAPContext* ctx) { std::stringstream cmdSS; switch (ctx->command) { - case IMAPContext::IMAP_SELECT: { - IMAPContext::Select* cmd = (IMAPContext::Select*)ctx->arguments; - cmdSS << "SELECT " << "\"" << cmd->mailbox << "\""; - break; - } - case IMAPContext::IMAP_EXAMINE: { - IMAPContext::Examine* cmd = (IMAPContext::Examine*)ctx->arguments; - cmdSS << "EXAMINE " << "\"" << cmd->mailbox << "\""; - break; - } - case IMAPContext::IMAP_CREATE: { - IMAPContext::Create* cmd = (IMAPContext::Create*)ctx->arguments; - cmdSS << "CREATE " << "\"" << cmd->mailbox << "\""; - break; - } - case IMAPContext::IMAP_DELETE: { - IMAPContext::Delete* cmd = (IMAPContext::Delete*)ctx->arguments; - cmdSS << "DELETE " << "\"" << cmd->mailbox << "\""; - break; - } - case IMAPContext::IMAP_RENAME: { - IMAPContext::Rename* cmd = (IMAPContext::Rename*)ctx->arguments; - cmdSS << "RENAME " << "\"" << cmd->mailbox << "\" \"" << cmd->newName << "\""; - break; - } - case IMAPContext::IMAP_SUBSCRIBE: { - IMAPContext::Subscribe* cmd = (IMAPContext::Subscribe*)ctx->arguments; - cmdSS << "SUBSCRIBE " << "\"" << cmd->mailbox << "\""; - break; - } - case IMAPContext::IMAP_UNSUBSCRIBE: { - IMAPContext::Unsubscribe* cmd = (IMAPContext::Unsubscribe*)ctx->arguments; - cmdSS << "UNSUBSCRIBE " << "\"" << cmd->mailbox << "\""; - break; - } - case IMAPContext::IMAP_LIST: { - IMAPContext::List* cmd = (IMAPContext::List*)ctx->arguments; - cmdSS << "LIST " << "\"" << cmd->mailbox << "\" \"" << cmd->refName << "\""; - break; - } - case IMAPContext::IMAP_LSUB: { - IMAPContext::LSub* cmd = (IMAPContext::LSub*)ctx->arguments; - cmdSS << "LSUB " << "\"" << cmd->mailbox << "\" \"" << cmd->refName << "\""; - break; - } - case IMAPContext::IMAP_STATUS: { - IMAPContext::Status* cmd = (IMAPContext::Status*)ctx->arguments; - cmdSS << "STATUS " << "\"" << cmd->mailbox << "\" (" << cmd->dataItems << ")"; - break; - } - case IMAPContext::IMAP_APPEND: { - IMAPContext::Append* cmd = (IMAPContext::Append*)ctx->arguments; - cmdSS << "APPEND " << "\"" << cmd->mailbox << "\" (" << cmd->flags << ") {" << cmd->dateTime << "}"; - break; - } - case IMAPContext::IMAP_CHECK: { - cmdSS << "CHECK"; - break; - } - case IMAPContext::IMAP_CLOSE: { - cmdSS << "CLOSE"; - break; - } - case IMAPContext::IMAP_EXPUNGE: { - cmdSS << "EXPUNGE"; - break; - } - case IMAPContext::IMAP_SEARCH: { - IMAPContext::Search* cmd = (IMAPContext::Search*)ctx->arguments; - cmdSS << "SEARCH "; - if (cmd->charSet.size() > 0) { - cmdSS << "CHARSET " << cmd->charSet << " "; - } - cmdSS << cmd->criteria; - break; - } - case IMAPContext::IMAP_FETCH: { - IMAPContext::Fetch* cmd = (IMAPContext::Fetch*)ctx->arguments; - cmdSS << "FETCH " << cmd->sequence << " " << cmd->itemNames; - break; - } - case IMAPContext::IMAP_STORE: { - IMAPContext::Store* cmd = (IMAPContext::Store*)ctx->arguments; - cmdSS << "STORE " << cmd->sequence << " " << cmd->itemNames << " " << cmd->values; - break; - } - case IMAPContext::IMAP_COPY: { - IMAPContext::Copy* cmd = (IMAPContext::Copy*)ctx->arguments; - cmdSS << "COPY " << "\"" << cmd->mailbox << "\" " << cmd->sequence; - break; - } - case IMAPContext::IMAP_UID: { - IMAPContext::UId* cmd = (IMAPContext::UId*)ctx->arguments; - cmdSS << "UID " << cmd->command << " " << cmd->arguments; - break; - } - case IMAPContext::IMAP_XEXTENSION: { - IMAPContext::XExtension* cmd = (IMAPContext::XExtension*)ctx->arguments; - cmdSS << cmd->command << " " << cmd->arguments; - break; + case IMAPContext::IMAP_SELECT: { + IMAPContext::Select* cmd = (IMAPContext::Select*)ctx->arguments; + cmdSS << "SELECT " << "\"" << cmd->mailbox << "\""; + break; + } + case IMAPContext::IMAP_EXAMINE: { + IMAPContext::Examine* cmd = (IMAPContext::Examine*)ctx->arguments; + cmdSS << "EXAMINE " << "\"" << cmd->mailbox << "\""; + break; + } + case IMAPContext::IMAP_CREATE: { + IMAPContext::Create* cmd = (IMAPContext::Create*)ctx->arguments; + cmdSS << "CREATE " << "\"" << cmd->mailbox << "\""; + break; + } + case IMAPContext::IMAP_DELETE: { + IMAPContext::Delete* cmd = (IMAPContext::Delete*)ctx->arguments; + cmdSS << "DELETE " << "\"" << cmd->mailbox << "\""; + break; + } + case IMAPContext::IMAP_RENAME: { + IMAPContext::Rename* cmd = (IMAPContext::Rename*)ctx->arguments; + cmdSS << "RENAME " << "\"" << cmd->mailbox << "\" \"" << cmd->newName << "\""; + break; + } + case IMAPContext::IMAP_SUBSCRIBE: { + IMAPContext::Subscribe* cmd = (IMAPContext::Subscribe*)ctx->arguments; + cmdSS << "SUBSCRIBE " << "\"" << cmd->mailbox << "\""; + break; + } + case IMAPContext::IMAP_UNSUBSCRIBE: { + IMAPContext::Unsubscribe* cmd = (IMAPContext::Unsubscribe*)ctx->arguments; + cmdSS << "UNSUBSCRIBE " << "\"" << cmd->mailbox << "\""; + break; + } + case IMAPContext::IMAP_LIST: { + IMAPContext::List* cmd = (IMAPContext::List*)ctx->arguments; + cmdSS << "LIST " << "\"" << cmd->mailbox << "\" \"" << cmd->refName << "\""; + break; + } + case IMAPContext::IMAP_LSUB: { + IMAPContext::LSub* cmd = (IMAPContext::LSub*)ctx->arguments; + cmdSS << "LSUB " << "\"" << cmd->mailbox << "\" \"" << cmd->refName << "\""; + break; + } + case IMAPContext::IMAP_STATUS: { + IMAPContext::Status* cmd = (IMAPContext::Status*)ctx->arguments; + cmdSS << "STATUS " << "\"" << cmd->mailbox << "\" (" << cmd->dataItems << ")"; + break; + } + case IMAPContext::IMAP_APPEND: { + IMAPContext::Append* cmd = (IMAPContext::Append*)ctx->arguments; + cmdSS << "APPEND " << "\"" << cmd->mailbox << "\" (" << cmd->flags << ") {" << cmd->dateTime << "}"; + break; + } + case IMAPContext::IMAP_CHECK: { + cmdSS << "CHECK"; + break; + } + case IMAPContext::IMAP_CLOSE: { + cmdSS << "CLOSE"; + break; + } + case IMAPContext::IMAP_EXPUNGE: { + cmdSS << "EXPUNGE"; + break; + } + case IMAPContext::IMAP_SEARCH: { + IMAPContext::Search* cmd = (IMAPContext::Search*)ctx->arguments; + cmdSS << "SEARCH "; + if (cmd->charSet.size() > 0) { + cmdSS << "CHARSET " << cmd->charSet << " "; } - default: - break; + cmdSS << cmd->criteria; + break; + } + case IMAPContext::IMAP_FETCH: { + IMAPContext::Fetch* cmd = (IMAPContext::Fetch*)ctx->arguments; + cmdSS << "FETCH " << cmd->sequence << " " << cmd->itemNames; + break; + } + case IMAPContext::IMAP_STORE: { + IMAPContext::Store* cmd = (IMAPContext::Store*)ctx->arguments; + cmdSS << "STORE " << cmd->sequence << " " << cmd->itemNames << " " << cmd->values; + break; + } + case IMAPContext::IMAP_COPY: { + IMAPContext::Copy* cmd = (IMAPContext::Copy*)ctx->arguments; + cmdSS << "COPY " << "\"" << cmd->mailbox << "\" " << cmd->sequence; + break; + } + case IMAPContext::IMAP_UID: { + IMAPContext::UId* cmd = (IMAPContext::UId*)ctx->arguments; + cmdSS << "UID " << cmd->command << " " << cmd->arguments; + break; + } + case IMAPContext::IMAP_XEXTENSION: { + IMAPContext::XExtension* cmd = (IMAPContext::XExtension*)ctx->arguments; + cmdSS << cmd->command << " " << cmd->arguments; + break; + } + default: + break; } curl_easy_setopt(_curl, CURLOPT_CUSTOMREQUEST, cmdSS.str().c_str()); CURLcode res = curl_easy_perform(_curl); - + /* Check for errors */ if(res != CURLE_OK) { LOG(ERROR) << "curl_easy_perform() failed: " << curl_easy_strerror(res); @@ -441,30 +441,30 @@ void IMAPInvoker::process(IMAPContext* ctx) { #if 0 switch (ctx->command) { - case IMAPContext::LIST: - e.data = parseListReponse(ctx->inContent.str()); - break; - default: - break; + case IMAPContext::LIST: + e.data = parseListReponse(ctx->inContent.str()); + break; + default: + break; } #endif - + e.name = ctx->sendReq.name + ".success"; e.data.compound["raw"] = Data(ctx->inContent.str(), Data::VERBATIM); returnEvent(e); } - + /* Always cleanup */ curl_easy_cleanup(_curl); - + } } #if 0 Data IMAPInvoker::parseListReponse(const std::string& response) { Data data; - + std::string line; std::istringstream inSS(response); @@ -472,14 +472,14 @@ Data IMAPInvoker::parseListReponse(const std::string& response) { // individual lines size_t lastSep = line.find_last_of("\" "); if (lastSep != std::string::npos) { - + } } - + return data; } #endif - + void IMAPInvoker::cancel(const std::string sendId) { } @@ -487,7 +487,7 @@ void IMAPInvoker::invoke(const InvokeRequest& req) { Event::getParam(req.params, "username", _username); Event::getParam(req.params, "password", _password); Event::getParam(req.params, "server", _server); - + _isRunning = true; _thread = new tthread::thread(IMAPInvoker::run, this); } diff --git a/src/uscxml/plugins/invoker/imap/IMAPInvoker.h b/src/uscxml/plugins/invoker/imap/IMAPInvoker.h index 94d199b..b1da324 100644 --- a/src/uscxml/plugins/invoker/imap/IMAPInvoker.h +++ b/src/uscxml/plugins/invoker/imap/IMAPInvoker.h @@ -52,37 +52,37 @@ public: protected: class IMAPContext { - + public: enum Cmd { - // valid in authenticated state - IMAP_SELECT, - IMAP_EXAMINE, - IMAP_CREATE, - IMAP_DELETE, - IMAP_RENAME, - IMAP_SUBSCRIBE, - IMAP_UNSUBSCRIBE, - IMAP_LIST, - IMAP_LSUB, - IMAP_STATUS, - IMAP_APPEND, - // valid in selected state - IMAP_CHECK, - IMAP_CLOSE, - IMAP_EXPUNGE, - IMAP_SEARCH, - IMAP_FETCH, - IMAP_STORE, - IMAP_COPY, - IMAP_UID, - IMAP_XEXTENSION, + // valid in authenticated state + IMAP_SELECT, + IMAP_EXAMINE, + IMAP_CREATE, + IMAP_DELETE, + IMAP_RENAME, + IMAP_SUBSCRIBE, + IMAP_UNSUBSCRIBE, + IMAP_LIST, + IMAP_LSUB, + IMAP_STATUS, + IMAP_APPEND, + // valid in selected state + IMAP_CHECK, + IMAP_CLOSE, + IMAP_EXPUNGE, + IMAP_SEARCH, + IMAP_FETCH, + IMAP_STORE, + IMAP_COPY, + IMAP_UID, + IMAP_XEXTENSION, }; struct MailboxOp { std::string mailbox; }; - + struct Select : MailboxOp {}; struct Examine : MailboxOp {}; struct Create : MailboxOp {}; @@ -127,12 +127,12 @@ protected: }; struct XExtension : UId {}; - + IMAPContext() : readPtr(0) {} void* arguments; Cmd command; - + IMAPInvoker* invoker; SendRequest sendReq; std::stringstream inContent; @@ -149,7 +149,7 @@ protected: std::string _server; static void run(void*); - + tthread::thread* _thread; uscxml::concurrency::BlockingQueue<IMAPContext*> _workQueue; bool _isRunning; diff --git a/src/uscxml/plugins/invoker/scxml/USCXMLInvoker.cpp b/src/uscxml/plugins/invoker/scxml/USCXMLInvoker.cpp index f1d9ad1..37ec669 100644 --- a/src/uscxml/plugins/invoker/scxml/USCXMLInvoker.cpp +++ b/src/uscxml/plugins/invoker/scxml/USCXMLInvoker.cpp @@ -82,15 +82,7 @@ void USCXMLInvoker::invoke(const InvokeRequest& req) { DataModel dataModel(_invokedInterpreter.getImpl()->getDataModel()); _invokedInterpreter.getImpl()->setParentQueue(&_parentQueue); // transfer namespace prefixes - _invokedInterpreter.getImpl()->_nsURL = _parentInterpreter->_nsURL; - _invokedInterpreter.getImpl()->_xpathPrefix = _parentInterpreter->_xpathPrefix; - _invokedInterpreter.getImpl()->_nsToPrefix = _parentInterpreter->_nsToPrefix; - std::map<std::string, std::string>::iterator nsIter = _parentInterpreter->_nsToPrefix.begin(); - while(nsIter != _parentInterpreter->_nsToPrefix.end()) { - _invokedInterpreter.getImpl()->_nsContext.addNamespaceDeclaration(nsIter->first, nsIter->second); - nsIter++; - } - _invokedInterpreter.getImpl()->_xmlNSPrefix = _parentInterpreter->_xmlNSPrefix; + _invokedInterpreter.setNameSpaceInfo(_parentInterpreter->getNameSpaceInfo()); _invokedInterpreter.getImpl()->_sessionId = req.invokeid; /// test240 assumes that invoke request params will carry over to the datamodel diff --git a/src/uscxml/plugins/invoker/umundo/UmundoInvoker.cpp b/src/uscxml/plugins/invoker/umundo/UmundoInvoker.cpp index 4129413..c84fd8f 100644 --- a/src/uscxml/plugins/invoker/umundo/UmundoInvoker.cpp +++ b/src/uscxml/plugins/invoker/umundo/UmundoInvoker.cpp @@ -73,20 +73,20 @@ void UmundoInvoker::send(const SendRequest& req) { } else { msg.putMeta("event", "umundo"); } - + try { Data data = req.data; - + if (!data && req.content.length()) data = _interpreter->getDataModel().getStringAsData(req.content); - + if (!data) { LOG(ERROR) << "Cannot transform content to data object per datamodel or no data given"; return; } // std::cout << Data::toJSON(data) << std::endl; - + std::string type; if (req.params.find("type") != req.params.end()) { // we are supposed to build a typed object diff --git a/src/uscxml/plugins/ioprocessor/scxml/SCXMLIOProcessor.cpp b/src/uscxml/plugins/ioprocessor/scxml/SCXMLIOProcessor.cpp index dda51b7..a080ff3 100644 --- a/src/uscxml/plugins/ioprocessor/scxml/SCXMLIOProcessor.cpp +++ b/src/uscxml/plugins/ioprocessor/scxml/SCXMLIOProcessor.cpp @@ -82,7 +82,7 @@ boost::shared_ptr<IOProcessorImpl> SCXMLIOProcessor::create(InterpreterImpl* int Data SCXMLIOProcessor::getDataModelVariables() { Data data; if(_url.length() > 0) - data.compound["location"] = Data(_url, Data::VERBATIM); + data.compound["location"] = Data(_url, Data::VERBATIM); return data; } diff --git a/src/uscxml/server/HTTPServer.cpp b/src/uscxml/server/HTTPServer.cpp index 69096fc..2d2b5e0 100644 --- a/src/uscxml/server/HTTPServer.cpp +++ b/src/uscxml/server/HTTPServer.cpp @@ -105,7 +105,7 @@ HTTPServer::HTTPServer(unsigned short port, unsigned short wsPort, SSLConfig* ss LOG(ERROR) << "HTTP server cannot bind to tcp/" << _port; } } - + _wsPort = wsPort; if (_wsPort > 0) { _wsHandle = evws_bind_socket(_evws, _wsPort); @@ -443,7 +443,7 @@ void HTTPServer::processByMatchingServlet(const Request& request) { if (servletIter->first.length() == 0) { matches.insert(std::make_pair(servletPath, servletIter->second)); // single servlet at root } else if (iequals(actualPath.substr(0, servletPath.length()), servletPath) && // servlet path is a prefix - iequals(actualPath.substr(servletPath.length(), 1), "/")) { // and next character is a '/' + iequals(actualPath.substr(servletPath.length(), 1), "/")) { // and next character is a '/' matches.insert(std::make_pair(servletPath, servletIter->second)); } servletIter++; @@ -530,7 +530,7 @@ void HTTPServer::replyCallback(evutil_socket_t fd, short what, void *arg) { delete(reply); } - + void HTTPServer::wsSend(struct evws_connection *conn, enum evws_opcode opcode, const char *data, uint64_t length) { HTTPServer* INSTANCE = getInstance(); WSData* sendCB = new WSData(conn, NULL, opcode, data, length); @@ -553,10 +553,10 @@ void HTTPServer::wsSendCallback(evutil_socket_t fd, short what, void *arg) { evws_send_data(wsSend->conn, wsSend->opcode, wsSend->data.data(), wsSend->data.length()); } } - + delete wsSend; } - + bool HTTPServer::registerServlet(const std::string& path, HTTPServlet* servlet) { HTTPServer* INSTANCE = getInstance(); diff --git a/src/uscxml/server/HTTPServer.h b/src/uscxml/server/HTTPServer.h index 2003130..09a31df 100644 --- a/src/uscxml/server/HTTPServer.h +++ b/src/uscxml/server/HTTPServer.h @@ -108,7 +108,7 @@ public: static void unregisterServlet(WebSocketServlet* servlet); private: - + class WSData { public: WSData(struct evws_connection *conn_, const char *uri_, enum evws_opcode opcode_, const char *data_, uint64_t length_) { @@ -147,7 +147,7 @@ private: static void httpRecvReqCallback(struct evhttp_request *req, void *callbackData); static void wsRecvReqCallback(struct evws_connection *conn, struct evws_frame *, void *callbackData); - + void processByMatchingServlet(const Request& request); void processByMatchingServlet(evws_connection* conn, const WSFrame& frame); diff --git a/src/uscxml/server/InterpreterServlet.cpp b/src/uscxml/server/InterpreterServlet.cpp index b956820..303aad0 100644 --- a/src/uscxml/server/InterpreterServlet.cpp +++ b/src/uscxml/server/InterpreterServlet.cpp @@ -155,23 +155,23 @@ void InterpreterWebSocketServlet::send(const SendRequest& req) { if (false) { } else if (req.data.binary) { HTTPServer::wsSend(_requests[req.target], - EVWS_BINARY_FRAME, - req.data.binary->data, - req.data.binary->size); + EVWS_BINARY_FRAME, + req.data.binary->data, + req.data.binary->size); } else if (req.data.node) { std::stringstream ssXML; ssXML << req.data.node; std::string data = ssXML.str(); HTTPServer::wsSend(_requests[req.target], - EVWS_TEXT_FRAME, - data.c_str(), - data.length()); + EVWS_TEXT_FRAME, + data.c_str(), + data.length()); } else if (req.data) { std::string data = Data::toJSON(req.data); HTTPServer::wsSend(_requests[req.target], - EVWS_TEXT_FRAME, - data.c_str(), - data.length()); + EVWS_TEXT_FRAME, + data.c_str(), + data.length()); } else { LOG(WARNING) << "Not sure what to make off content given to send on websocket!"; } @@ -180,23 +180,23 @@ void InterpreterWebSocketServlet::send(const SendRequest& req) { if (false) { } else if (req.data.binary) { HTTPServer::wsBroadcast(req.target.c_str(), - EVWS_BINARY_FRAME, - req.data.binary->data, - req.data.binary->size); + EVWS_BINARY_FRAME, + req.data.binary->data, + req.data.binary->size); } else if (req.data.node) { std::stringstream ssXML; ssXML << req.data.node; std::string data = ssXML.str(); HTTPServer::wsBroadcast(req.target.c_str(), - EVWS_TEXT_FRAME, - data.c_str(), - data.length()); + EVWS_TEXT_FRAME, + data.c_str(), + data.length()); } else if (req.data) { std::string data = Data::toJSON(req.data); HTTPServer::wsBroadcast(req.target.c_str(), - EVWS_TEXT_FRAME, - data.c_str(), - data.length()); + EVWS_TEXT_FRAME, + data.c_str(), + data.length()); } else { LOG(WARNING) << "Not sure what to make off content given to broadcast on websocket!"; } diff --git a/src/uscxml/transform/ChartToFSM.cpp b/src/uscxml/transform/ChartToFSM.cpp index d962481..8b1725c 100644 --- a/src/uscxml/transform/ChartToFSM.cpp +++ b/src/uscxml/transform/ChartToFSM.cpp @@ -19,6 +19,8 @@ #include "uscxml/transform/ChartToFSM.h" #include <DOM/io/Stream.hpp> +#include <glog/logging.h> + #include <iostream> #include "uscxml/UUID.h" #include <math.h> @@ -34,7 +36,9 @@ using namespace Arabica::XPath; #define CREATE_TRANSIENT_STATE_WITH_CHILDS \ if (childs.size() > 0) { \ - Element<std::string> transientState = _flatDoc.createElementNS(xmlNs, "state"); \ + Element<std::string> transientState = _flatDoc.createElementNS(_nsInfo.nsURL, "state"); \ + _nsInfo.setPrefix(transientState);\ + transientState.setAttribute("transient", "true"); \ for (int i = 0; i < childs.size(); i++) { \ Node<std::string> imported = _flatDoc.importNode(childs[i], true); \ transientState.appendChild(imported); \ @@ -43,19 +47,24 @@ if (childs.size() > 0) { \ } \ childs = NodeSet<std::string>(); -Document<std::string> ChartToFSM::flatten(const Document<std::string>& doc, const std::map<std::string, std::string>& nameSpaceInfo) { - boost::shared_ptr<InterpreterImpl> flatInterpreter = boost::shared_ptr<InterpreterImpl>(new FlatteningInterpreter(doc)); - flatInterpreter->setNameSpaceInfo(nameSpaceInfo); - flatInterpreter->interpret(); - return flatInterpreter->getDocument(); +Interpreter ChartToFSM::flatten(const Interpreter& other) { + + // instantiate a new InterpreterImpl to do the flattening + boost::shared_ptr<InterpreterImpl> flattener = boost::shared_ptr<InterpreterImpl>(new FlatteningInterpreter(other.getDocument())); + flattener->setNameSpaceInfo(other.getNameSpaceInfo()); + flattener->interpret(); + + // clone the flattener implementation to a new interpreter + Interpreter flat = Interpreter::fromClone(flattener); + return flat; } FlatteningInterpreter::FlatteningInterpreter(const Document<std::string>& doc) { - + _currGlobalTransition = NULL; - - // kust copy given doc into _document an create _flatDoc for the FSM + + // just copy given doc into _document an create _flatDoc for the FSM DOMImplementation<std::string> domFactory = Arabica::SimpleDOM::DOMImplementation<std::string>::getDOMImplementation(); _document = domFactory.createDocument(doc.getNamespaceURI(), "", 0); _flatDoc = domFactory.createDocument(doc.getNamespaceURI(), "", 0); @@ -70,10 +79,24 @@ FlatteningInterpreter::FlatteningInterpreter(const Document<std::string>& doc) { addMonitor(this); } -Document<std::string>& FlatteningInterpreter::getDocument() { - std::cout << "######################" << std::endl; - std::cout << _flatDoc << std::endl; - std::cout << "######################" << std::endl; +FlatteningInterpreter::~FlatteningInterpreter() { + std::map<std::string, GlobalState*>::iterator confIter = _globalConf.begin(); + while(confIter != _globalConf.end()) { + std::map<std::string, GlobalTransition*>::iterator transIter = confIter->second->outgoing.begin(); + while (transIter != confIter->second->outgoing.end()) { + delete transIter->second; + transIter++; + } + delete confIter->second; + confIter++; + } + +} + +Document<std::string> FlatteningInterpreter::getDocument() const { +// std::cout << "######################" << std::endl; +// std::cout << _flatDoc << std::endl; +// std::cout << "######################" << std::endl; return _flatDoc; } @@ -81,7 +104,7 @@ void FlatteningInterpreter::interpret() { init(); setupIOProcessors(); - + // initialize the datamodel std::string datamodelName; if (datamodelName.length() == 0 && HAS_ATTR(_scxml, "datamodel")) @@ -99,20 +122,19 @@ void FlatteningInterpreter::interpret() { _dataModel = _factory->createDataModel("null", this); } if(datamodelName.length() > 0 && !_dataModel) { - std::cout << "No datamodel for " << datamodelName << " registered"; - } - - if (_dataModel) { - _dataModel.assign("_x.args", _cmdLineOptions); + LOG(ERROR) << "No datamodel for " << datamodelName << " registered"; } - + _binding = (HAS_ATTR(_scxml, "binding") && iequals(ATTR(_scxml, "binding"), "late") ? LATE : EARLY); - + // reset + _globalConf.clear(); + _currGlobalTransition = NULL; + // very first state _start = new GlobalState(_configuration, _alreadyEntered, _historyValue); _globalConf[_start->stateId] = _start; - + NodeSet<std::string> initialTransitions; // enter initial configuration @@ -120,9 +142,11 @@ void FlatteningInterpreter::interpret() { initialStates = getInitialStates(); assert(initialStates.size() > 0); for (int i = 0; i < initialStates.size(); i++) { - Element<std::string> initialElem = _document.createElementNS(_nsURL, "initial"); + Element<std::string> initialElem = _document.createElementNS(_nsInfo.nsURL, "initial"); + _nsInfo.setPrefix(initialElem); initialElem.setAttribute("generated", "true"); - Element<std::string> transitionElem = _document.createElementNS(_nsURL, "transition"); + Element<std::string> transitionElem = _document.createElementNS(_nsInfo.nsURL, "transition"); + _nsInfo.setPrefix(transitionElem); transitionElem.setAttribute("target", ATTR(initialStates[i], "id")); initialElem.appendChild(transitionElem); _scxml.appendChild(initialElem); @@ -130,8 +154,8 @@ void FlatteningInterpreter::interpret() { } labelTransitions(); weightTransitions(); - - std::cout << _scxml << std::endl; + +// std::cout << _scxml << std::endl; GlobalTransition* globalTransition = new GlobalTransition(initialTransitions, _dataModel); _start->outgoing[globalTransition->transitionId] = globalTransition; @@ -140,22 +164,22 @@ void FlatteningInterpreter::interpret() { enterStates(initialTransitions); explode(); - + #if 0 // print set of global configurations for(std::map<std::string, GlobalState*>::iterator globalConfIter = _globalConf.begin(); - globalConfIter != _globalConf.end(); - globalConfIter++) { + globalConfIter != _globalConf.end(); + globalConfIter++) { std::cout << globalConfIter->first << std::endl; } std::cout << _globalConf.size() << std::endl; #endif - + createDocument(); } void FlatteningInterpreter::executeContent(const Arabica::DOM::Node<std::string>& content, bool rethrow) { - std::cout << content << std::endl; +// std::cout << content << std::endl; GlobalTransition::Action action; if (false) { @@ -199,51 +223,55 @@ void FlatteningInterpreter::cancelInvoke(const Arabica::DOM::Node<std::string>& } void FlatteningInterpreter::internalDoneSend(const Arabica::DOM::Node<std::string>& state) { - + if (!isState(state)) return; Arabica::DOM::Element<std::string> stateElem = (Arabica::DOM::Element<std::string>)state; // if (parentIsScxmlState(state)) // return; - + // std::cout << "internalDoneSend: " << state << std::endl; - + // create onentry with a raise element - Element<std::string> onentry = _flatDoc.createElement("onentry"); - Element<std::string> raise = _flatDoc.createElement("raise"); + Element<std::string> onentry = _flatDoc.createElementNS(_nsInfo.nsURL, "onentry"); + _nsInfo.setPrefix(onentry); + + Element<std::string> raise = _flatDoc.createElementNS(_nsInfo.nsURL, "raise"); + _nsInfo.setPrefix(raise); + onentry.appendChild(raise); - Arabica::XPath::NodeSet<std::string> doneDatas = filterChildElements(_xmlNSPrefix + "donedata", stateElem); + Arabica::XPath::NodeSet<std::string> doneDatas = filterChildElements(_nsInfo.xmlNSPrefix + "donedata", stateElem); if (doneDatas.size() > 0) { Arabica::DOM::Node<std::string> doneData = doneDatas[0]; - Arabica::XPath::NodeSet<std::string> contents = filterChildElements(_xmlNSPrefix + "content", doneDatas[0]); + Arabica::XPath::NodeSet<std::string> contents = filterChildElements(_nsInfo.xmlNSPrefix + "content", doneDatas[0]); if (contents.size() > 0) { Node<std::string> imported = _flatDoc.importNode(contents[0], true); raise.appendChild(imported); } - Arabica::XPath::NodeSet<std::string> params = filterChildElements(_xmlNSPrefix + "param", doneDatas[0]); + Arabica::XPath::NodeSet<std::string> params = filterChildElements(_nsInfo.xmlNSPrefix + "param", doneDatas[0]); if (params.size() > 0) { Node<std::string> imported = _flatDoc.importNode(params[0], true); raise.appendChild(imported); } } - + raise.setAttribute("event", "done.state." + ATTR(stateElem.getParentNode(), "id")); // parent?! - + GlobalTransition::Action action; action.onEntry = onentry; - + _currGlobalTransition->actions.push_back(action); - + } static bool isSuperset(const GlobalTransition* t1, const GlobalTransition* t2) { bool isSuperset = true; - + if (t1->transitions.size() >= t2->transitions.size()) return false; - + for (int i = 0; i < t1->transitions.size(); i++) { if (!InterpreterImpl::isMember(t1->transitions[i], t2->transitions)) { isSuperset = false; @@ -251,7 +279,7 @@ static bool isSuperset(const GlobalTransition* t1, const GlobalTransition* t2) { } return isSuperset; } - + static NodeSet<std::string> filterChildEnabled(const NodeSet<std::string>& transitions) { // drop any transition that is already enabled by a child NodeSet<std::string> filteredTransitions; @@ -269,7 +297,7 @@ static NodeSet<std::string> filterChildEnabled(const NodeSet<std::string>& trans std::string eventDesc1 = ATTR(t1, "event"); std::string eventDesc2 = ATTR(t2, "event"); if (InterpreterImpl::nameMatch(eventDesc1, eventDesc2)) { - std::cout << "Dropping " << t1 << std::endl << "for " << t2 << std::endl; +// std::cout << "Dropping " << t1 << std::endl << "for " << t2 << std::endl; goto SKIP_TRANSITION; } } @@ -277,7 +305,8 @@ static NodeSet<std::string> filterChildEnabled(const NodeSet<std::string>& trans } } filteredTransitions.push_back(t1); - SKIP_TRANSITION:; +SKIP_TRANSITION: + ; } return filteredTransitions; } @@ -286,14 +315,14 @@ static std::list<GlobalTransition*> sortTransitions(std::list<GlobalTransition*> bool stable = false; while(!stable) { 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++) { GlobalTransition* t1 = *outerIter; GlobalTransition* t2 = *innerIter; - + if (isSuperset(t1, t2)) { // std::cout << "swapping " << t1->transitionId << " / " << t2->transitionId << std::endl; std::swap(*innerIter, *outerIter); @@ -313,7 +342,8 @@ static std::list<GlobalTransition*> sortTransitions(std::list<GlobalTransition*> } } stable = true; - NEXT_ITER:; +NEXT_ITER: + ; } return list; } @@ -321,7 +351,7 @@ static std::list<GlobalTransition*> sortTransitions(std::list<GlobalTransition*> void FlatteningInterpreter::explode() { - + // save global configuration elements to restore after recursive explode Arabica::XPath::NodeSet<std::string> configuration = _configuration; Arabica::XPath::NodeSet<std::string> alreadyEntered = _alreadyEntered; @@ -334,19 +364,19 @@ void FlatteningInterpreter::explode() { if (_currGlobalTransition) { _currGlobalTransition->destination = globalState->stateId; globalState->incoming[_currGlobalTransition->transitionId] = _currGlobalTransition; - + // if (!_currGlobalTransition->isEventless) { - // if it was an eventful transition, add all invokers - for (unsigned int i = 0; i < _statesToInvoke.size(); i++) { - NodeSet<std::string> invokes = filterChildElements(_xmlNSPrefix + "invoke", _statesToInvoke[i]); - for (unsigned int j = 0; j < invokes.size(); j++) { - invoke(invokes[j]); - } + // if it was an eventful transition, add all invokers + for (unsigned int i = 0; i < _statesToInvoke.size(); i++) { + NodeSet<std::string> invokes = filterChildElements(_nsInfo.xmlNSPrefix + "invoke", _statesToInvoke[i]); + for (unsigned int j = 0; j < invokes.size(); j++) { + invoke(invokes[j]); } - _statesToInvoke = NodeSet<std::string>(); + } + _statesToInvoke = NodeSet<std::string>(); // } } - + if (_globalConf.find(globalState->stateId) != _globalConf.end()) { delete globalState; return; // we have already been here @@ -354,8 +384,8 @@ void FlatteningInterpreter::explode() { _globalConf[globalState->stateId] = globalState; // get all transition elements from states in the current configuration - NodeSet<std::string> allTransitions = filterChildElements(_xmlNSPrefix + "transition", configuration); - + NodeSet<std::string> allTransitions = filterChildElements(_nsInfo.xmlNSPrefix + "transition", configuration); + /** * From http://www.w3.org/TR/scxml/#SelectingTransitions * @@ -365,8 +395,8 @@ void FlatteningInterpreter::explode() { * c) T lacks a 'cond' attribute or its 'cond' attribute evaluates to "true" * * A transition is enabled by NULL in atomic state S if - * a) T lacks an 'event' attribute - * b) T's source state is S or an ancestor of S + * a) T lacks an 'event' attribute + * b) T's source state is S or an ancestor of S * c) T lacks an 'cond' attribute or its 'cond' attribute evaluates to "true" * * The _source state_ of a transition is the <state> or <parallel> element that it occurs in. @@ -380,14 +410,14 @@ void FlatteningInterpreter::explode() { * * Two transitions T1 and T2 conflict in state configuration C if their exit sets in C have a non-null intersection. * let transitions T1 and T2 conflict: - * T1 is optimally enabled in atomic state S1 + * T1 is optimally enabled in atomic state S1 * T2 is optimally enabled in atomic state S2 * S1 and S2 are both active * T1 has a higher priority than T2 if: * a) T1's source state is a descendant of T2's source state, or * b) S1 precedes S2 in document order * - * The _optimal transition set_ enabled by event E in state configuration C is + * The _optimal transition set_ enabled by event E in state configuration C is * the largest set of transitions such that: * a) each transition in the set is optimally enabled by E in an atomic state in C * b) no transition conflicts with another transition in the set @@ -395,14 +425,14 @@ void FlatteningInterpreter::explode() { * * A _microstep_ consists of the execution of the transitions in an optimal enabled transition set * - * A _macrostep_ is a series of one or more microsteps ending in a configuration + * A _macrostep_ is a series of one or more microsteps ending in a configuration * where the internal event queue is empty and no transitions are enabled by NULL */ - - + + if (allTransitions.size() == 0) return; // no transitions - + int nrElements = allTransitions.size(); int k = 0; int* stack = (int*)malloc((nrElements + 1) * sizeof(int)); @@ -414,17 +444,17 @@ void FlatteningInterpreter::explode() { while(1) { // create the power set of all potential transitions // see: http://www.programminglogic.com/powerset-algorithm-in-c/ - - if (stack[k] < nrElements){ + + if (stack[k] < nrElements) { stack[k+1] = stack[k] + 1; k++; } - + else { stack[k-1]++; k--; } - + if (k==0) break; @@ -438,10 +468,10 @@ void FlatteningInterpreter::explode() { // reduce to conflict-free subset transitions = filterPreempted(transitions); - + // algorithm can never reduce to empty set assert(transitions.size() > 0); - + // create a GlobalTransition object from the set GlobalTransition* transition = new GlobalTransition(transitions, _dataModel); if (!transition->isValid) { @@ -452,7 +482,7 @@ void FlatteningInterpreter::explode() { // two combinations might have projected onto the same conflict-free set if (transitionSets.find(transition->transitionId) != transitionSets.end()) { - std::cout << "skipping as projected onto existing conflict-free subset" << std::endl; +// std::cout << "skipping as projected onto existing conflict-free subset" << std::endl; delete transition; continue; } @@ -475,7 +505,7 @@ void FlatteningInterpreter::explode() { transition->firstElemPerLevel.push_back(lowestOrder); transition->prioPerLevel.push_back(prioPerLevel); } - + #if 0 // calculate priority transition->priority = 0; @@ -495,25 +525,26 @@ void FlatteningInterpreter::explode() { goto NEXT_DEPTH; } } - NEXT_DEPTH:; +NEXT_DEPTH: + ; } #endif // remember this conflict-free set - std::cout << "New conflict-free subset: " << transition->transitionId << ":" << transition->eventDesc << std::endl; +// std::cout << "New conflict-free subset: " << transition->transitionId << ":" << transition->eventDesc << std::endl; transitionSets[transition->transitionId] = transition; } // TODO: reduce and sort transition sets std::list<GlobalTransition*> transitionList; for(std::map<std::string, GlobalTransition*>::iterator transSetIter = transitionSets.begin(); - transSetIter != transitionSets.end(); - transSetIter++) { + transSetIter != transitionSets.end(); + transSetIter++) { transitionList.push_back(transSetIter->second); } - + for(std::list<GlobalTransition*>::iterator transListIter = transitionList.begin(); - transListIter != transitionList.end(); - transListIter++) { + transListIter != transitionList.end(); + transListIter++) { // add transition set to current global state globalState->outgoing[(*transListIter)->transitionId] = *transListIter; @@ -522,7 +553,7 @@ void FlatteningInterpreter::explode() { _currGlobalTransition = *transListIter; microstep((*transListIter)->transitions); explode(); - + // reset state for next transition set _configuration = configuration; _alreadyEntered = alreadyEntered; @@ -530,12 +561,13 @@ void FlatteningInterpreter::explode() { } } - + void FlatteningInterpreter::createDocument() { - std::string xmlNs = _nsURL; Node<std::string> _origSCXML = _scxml; - - _scxml = _flatDoc.createElementNS(xmlNs, "scxml"); + + _scxml = _flatDoc.createElementNS(_nsInfo.nsURL, "scxml"); + _nsInfo.setPrefix(_scxml); + _scxml.setAttribute("flat", "true"); _flatDoc.appendChild(_scxml); @@ -546,16 +578,16 @@ void FlatteningInterpreter::createDocument() { 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 - datas = filterChildElements(_xmlNSPrefix + "datamodel", _origSCXML); + datas = filterChildElements(_nsInfo.xmlNSPrefix + "datamodel", _origSCXML); } else { // with early binding, copy all datamodel elements into scxml element - datas = _xpath.evaluate("//" + _xpathPrefix + "datamodel", _origSCXML).asNodeSet(); + datas = _xpath.evaluate("//" + _nsInfo.xpathPrefix + "datamodel", _origSCXML).asNodeSet(); } for (int i = 0; i < datas.size(); i++) { if (isInEmbeddedDocument(datas[i])) @@ -564,25 +596,33 @@ void FlatteningInterpreter::createDocument() { _scxml.appendChild(imported); } - - NodeSet<std::string> scripts = filterChildElements(_xmlNSPrefix + "script", _origSCXML); + + 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); + } + for (std::map<std::string, GlobalState*>::iterator confIter = _globalConf.begin(); - confIter != _globalConf.end(); - confIter++) { - Node<std::string> state = globalStateToNode(confIter->second, xmlNs); + confIter != _globalConf.end(); + confIter++) { + Node<std::string> state = globalStateToNode(confIter->second); _scxml.appendChild(state); } // exit(0); } -Node<std::string> FlatteningInterpreter::globalStateToNode(GlobalState* globalState, const std::string& xmlNs) { - Element<std::string> state = _flatDoc.createElementNS(xmlNs, "state"); +Node<std::string> FlatteningInterpreter::globalStateToNode(GlobalState* globalState) { + Element<std::string> state = _flatDoc.createElementNS(_nsInfo.nsURL, "state"); + _nsInfo.setPrefix(state); + state.setAttribute("id", globalState->stateId); if (globalState->isFinal) @@ -590,20 +630,20 @@ Node<std::string> FlatteningInterpreter::globalStateToNode(GlobalState* globalSt std::list<GlobalTransition*> transitionList; for (std::map<std::string, GlobalTransition*>::iterator outIter = globalState->outgoing.begin(); - outIter != globalState->outgoing.end(); - outIter++) { + outIter != globalState->outgoing.end(); + outIter++) { transitionList.push_back(outIter->second); } transitionList = sortTransitions(transitionList); - - std::cout << "/////////////////" << std::endl; + +// std::cout << "/////////////////" << std::endl; for (std::list<GlobalTransition*>::iterator outIter = transitionList.begin(); - outIter != transitionList.end(); - outIter++) { - state.appendChild(globalTransitionToNode(*outIter, xmlNs)); + outIter != transitionList.end(); + outIter++) { + state.appendChild(globalTransitionToNode(*outIter)); } - std::cout << "/////////////////" << std::endl; +// std::cout << "/////////////////" << std::endl; return state; } @@ -611,8 +651,9 @@ Node<std::string> FlatteningInterpreter::globalStateToNode(GlobalState* globalSt /** * Creates transient states for executable content as a side-effect */ -Node<std::string> FlatteningInterpreter::globalTransitionToNode(GlobalTransition* globalTransition, const std::string& xmlNs) { - Element<std::string> transition = _flatDoc.createElementNS(xmlNs, "transition"); +Node<std::string> FlatteningInterpreter::globalTransitionToNode(GlobalTransition* globalTransition) { + Element<std::string> transition = _flatDoc.createElementNS(_nsInfo.nsURL, "transition"); + _nsInfo.setPrefix(transition); if (!globalTransition->isEventless) { transition.setAttribute("event", globalTransition->eventDesc); @@ -649,25 +690,26 @@ Node<std::string> FlatteningInterpreter::globalTransitionToNode(GlobalTransition } transition.setAttribute("prioPerLevel", nrSS.str()); #endif - + transition.setAttribute("id", globalTransition->transitionId); - + // std::cout << " firstPerLevel:" << feSS.str() << " " << globalTransition->transitionId << std::endl; // std::cout << "event: " << globalTransition->eventDesc << " firstPerLevel:" << feSS.str() << " numberPerLevel:" << nrSS.str() << " prioPerLevel:" << prSS.str() << " " << globalTransition->transitionId << std::endl; // std::cout << globalTransition->transitionId << std::endl; - + NodeSet<std::string> transientStateChain; // gather content for new transient state NodeSet<std::string> childs; - + // iterate all actions taken during the transition for (std::list<GlobalTransition::Action>::iterator actionIter = globalTransition->actions.begin(); - actionIter != globalTransition->actions.end(); - actionIter++) { - + actionIter != globalTransition->actions.end(); + actionIter++) { + if (actionIter->transition) { - Element<std::string> onexit = _flatDoc.createElementNS(xmlNs, "onexit"); + Element<std::string> onexit = _flatDoc.createElementNS(_nsInfo.nsURL, "onexit"); + _nsInfo.setPrefix(onexit); Node<std::string> child = actionIter->transition.getFirstChild(); while(child) { Node<std::string> imported = _flatDoc.importNode(child, true); @@ -700,7 +742,9 @@ Node<std::string> FlatteningInterpreter::globalTransitionToNode(GlobalTransition } if (actionIter->uninvoke) { - Element<std::string> uninvokeElem = _flatDoc.createElementNS(xmlNs, "uninvoke"); + 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")); } @@ -720,7 +764,7 @@ Node<std::string> FlatteningInterpreter::globalTransitionToNode(GlobalTransition if (actionIter->entered) { // 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(_xmlNSPrefix + "datamodel", actionIter->entered); + NodeSet<std::string> datamodel = filterChildElements(_nsInfo.xmlNSPrefix + "datamodel", actionIter->entered); if (datamodel.size() > 0 && !isMember(actionIter->entered, _globalConf[globalTransition->source]->alreadyEnteredStates)) { childs.push_back(datamodel); } @@ -740,43 +784,44 @@ Node<std::string> FlatteningInterpreter::globalTransitionToNode(GlobalTransition } CREATE_TRANSIENT_STATE_WITH_CHILDS - + if (transientStateChain.size() > 0) { for (int i = 0; i < transientStateChain.size(); i++) { Element<std::string> transientStateElem = Element<std::string>(transientStateChain[i]); transientStateElem.setAttribute("id", "transient-" + globalTransition->transitionId + "-" + globalTransition->source + "-" + toStr(i)); - Element<std::string> exitTransition = _flatDoc.createElementNS(xmlNs, "transition"); - + Element<std::string> exitTransition = _flatDoc.createElementNS(_nsInfo.nsURL, "transition"); + _nsInfo.setPrefix(exitTransition); + if (i == transientStateChain.size() - 1) { exitTransition.setAttribute("target", globalTransition->destination); } else { exitTransition.setAttribute("target", "transient-" + globalTransition->transitionId + "-" + globalTransition->source + "-" + toStr(i + 1)); } transientStateElem.appendChild(exitTransition); - + if (i == 0) transition.setAttribute("target", transientStateElem.getAttribute("id")); - + _scxml.appendChild(transientStateElem); } } else { transition.setAttribute("target", globalTransition->destination); } - + return transition; } void FlatteningInterpreter::weightTransitions() { maxDepth = 0; maxOrder = 0; - + int depth = 0; Arabica::XPath::NodeSet<std::string> states = getChildStates(_scxml); while(states.size() > 0) { - NodeSet<std::string> transitions = filterChildElements(_xmlNSPrefix + "transition", states); - NodeSet<std::string> initials = filterChildElements(_xmlNSPrefix + "initial", states); - transitions.push_back(filterChildElements(_xmlNSPrefix + "transition", initials)); + NodeSet<std::string> transitions = filterChildElements(_nsInfo.xmlNSPrefix + "transition", states); + NodeSet<std::string> initials = filterChildElements(_nsInfo.xmlNSPrefix + "initial", states); + transitions.push_back(filterChildElements(_nsInfo.xmlNSPrefix + "transition", initials)); for (int j = 0; j < transitions.size(); j++) { if (depth > maxDepth) @@ -791,24 +836,24 @@ void FlatteningInterpreter::weightTransitions() { states = getChildStates(states); } } - + void FlatteningInterpreter::labelTransitions() { // put a unique id on each transition Arabica::XPath::NodeSet<std::string> states = getAllStates(); states.push_back(_scxml); for (int i = 0; i < states.size(); i++) { std::string stateId = ATTR(states[i], "id"); - NodeSet<std::string> transitions = filterChildElements(_xmlNSPrefix + "transition", states[i]); + NodeSet<std::string> transitions = filterChildElements(_nsInfo.xmlNSPrefix + "transition", states[i]); // some transitions are in the inital elements - NodeSet<std::string> initials = filterChildElements(_xmlNSPrefix + "initial", states[i]); - transitions.push_back(filterChildElements(_xmlNSPrefix + "transition", initials)); + NodeSet<std::string> initials = filterChildElements(_nsInfo.xmlNSPrefix + "initial", states[i]); + transitions.push_back(filterChildElements(_nsInfo.xmlNSPrefix + "transition", initials)); for (int j = 0; j < transitions.size(); j++) { Element<std::string> transition = Element<std::string>(transitions[j]); transition.setAttribute("id", stateId + ":"+ toStr(j + 1)); } } } - + void FlatteningInterpreter::beforeMicroStep(Interpreter interpreter) { } void FlatteningInterpreter::onStableConfiguration(Interpreter interpreter) { @@ -828,31 +873,31 @@ void FlatteningInterpreter::beforeEnteringState(Interpreter interpreter, const A void FlatteningInterpreter::beforeTakingTransition(Interpreter interpreter, const Arabica::DOM::Element<std::string>& transition, bool moreComing) { } - + GlobalState::GlobalState(const Arabica::XPath::NodeSet<std::string>& activeStates_, - const Arabica::XPath::NodeSet<std::string>& alreadyEnteredStates_, // we need to remember for binding=late - const std::map<std::string, Arabica::XPath::NodeSet<std::string> >& historyStates_) { - + const Arabica::XPath::NodeSet<std::string>& alreadyEnteredStates_, // we need to remember for binding=late + const std::map<std::string, Arabica::XPath::NodeSet<std::string> >& historyStates_) { + // make copies and sort activeStates = activeStates_; alreadyEnteredStates = alreadyEnteredStates_; historyStates = historyStates_; isFinal = true; // is set to false if we contain a non-final state - + // start state is not final if (activeStates.size() == 0) { isFinal = false; } - + // sort configuration activeStates.to_document_order(); alreadyEnteredStates.to_document_order(); for(std::map<std::string, Arabica::XPath::NodeSet<std::string> >::iterator historyIter = historyStates.begin(); - historyIter != historyStates.end(); - historyIter++) { + historyIter != historyStates.end(); + historyIter++) { historyIter->second.to_document_order(); } - + // create a unique identifier for a global configuration std::ostringstream idSS; idSS << "active-"; @@ -867,10 +912,10 @@ GlobalState::GlobalState(const Arabica::XPath::NodeSet<std::string>& activeState idSS << ATTR(alreadyEnteredStates[i], "id") << "-"; } idSS << ";"; - + for(std::map<std::string, Arabica::XPath::NodeSet<std::string> >::const_iterator histIter = historyStates.begin(); - histIter != historyStates.end(); - histIter++) { + histIter != historyStates.end(); + histIter++) { const Arabica::XPath::NodeSet<std::string>& histStates = histIter->second; idSS << "history-"; idSS << histIter->first << "-"; @@ -878,7 +923,7 @@ GlobalState::GlobalState(const Arabica::XPath::NodeSet<std::string>& activeState idSS << ATTR(histStates[i], "id") << "-"; } } - + stateId = idSS.str(); } @@ -886,7 +931,7 @@ GlobalTransition::GlobalTransition(const Arabica::XPath::NodeSet<std::string>& t transitions = transitionSet; isValid = true; isEventless = true; - + #if 0 std::cout << "################" << std::endl; for (int i = 0; i < transitions.size(); i++) { @@ -894,14 +939,14 @@ GlobalTransition::GlobalTransition(const Arabica::XPath::NodeSet<std::string>& t } std::cout << "################" << std::endl; #endif - + std::list<std::string> conditions; std::ostringstream setId; // also build id for subset for (int i = 0; i < transitions.size(); i++) { // get a unique string for the transition - we assume it is sorted assert(HAS_ATTR(transitions[i], "id")); setId << ATTR(transitions[i], "id") << "-"; - + // gather conditions while we are iterating anyway if (HAS_ATTR(transitions[i], "cond")) { conditions.push_back(ATTR(transitions[i], "cond")); @@ -920,7 +965,7 @@ GlobalTransition::GlobalTransition(const Arabica::XPath::NodeSet<std::string>& t bool foundEventLess = false; bool foundWithTarget = false; bool foundTargetLess = false; - + for (int i = 0; i < transitions.size(); i++) { if (HAS_ATTR(transitions[i], "eventexpr")) { Event e("error.execution", Event::PLATFORM); @@ -947,7 +992,7 @@ GlobalTransition::GlobalTransition(const Arabica::XPath::NodeSet<std::string>& t } } - + // do not mix eventless and event transitions if (foundEventLess && foundWithEvent) { isValid = false; @@ -962,20 +1007,20 @@ GlobalTransition::GlobalTransition(const Arabica::XPath::NodeSet<std::string>& t isEventless = foundEventLess; isTargetless = !foundWithTarget; - + // is there a set of event names that would enable this conflict-free transition set? if (foundWithEvent) { // get the set of longest event descriptors that will enable this transition set eventNames = getCommonEvents(transitions); if (eventNames.size() == 0) { - std::cout << "No event will activate this conflict-free subset" << std::endl; +// LOG(INFO) << "No event will activate this conflict-free subset" << std::endl; isValid = false; return; } else { std::string seperator = ""; for (std::list<std::string>::iterator eventIter = eventNames.begin(); - eventIter != eventNames.end(); - eventIter++) { + eventIter != eventNames.end(); + eventIter++) { eventDesc += seperator + *eventIter; seperator = " "; } @@ -983,35 +1028,35 @@ GlobalTransition::GlobalTransition(const Arabica::XPath::NodeSet<std::string>& t if (eventDesc.size() == 0) eventDesc = "*"; } - + if (conditions.size() > 0) { condition = dataModel.andExpressions(conditions); if (condition.size() == 0) { - std::cout << "Datamodel does not support to conjungate expressions!" << std::endl; + LOG(ERROR) << "Datamodel does not support to conjungate expressions!" << std::endl; } } } - + std::list<std::string> GlobalTransition::getCommonEvents(const NodeSet<std::string>& transitions) { std::list<std::string> prefixes; std::list<std::string> longestPrefixes; - + for (int i = 0; i < transitions.size(); i++) { // for every transition std::list<std::string> eventNames = Interpreter::tokenizeIdRefs(ATTR(transitions[i], "event")); - + for (std::list<std::string>::iterator eventNameIter = eventNames.begin(); - eventNameIter != eventNames.end(); - eventNameIter++) { + eventNameIter != eventNames.end(); + eventNameIter++) { // for every event descriptor std::string eventName = *eventNameIter; - + // remove trailing .* if (eventName.find("*", eventName.size() - 1) != std::string::npos) eventName = eventName.substr(0, eventName.size() - 1); if (eventName.find(".", eventName.size() - 1) != std::string::npos) eventName = eventName.substr(0, eventName.size() - 1); - + bool isMatching = true; for (int j = 0; j < transitions.size(); j++) { // check if token would activate all other transitions @@ -1027,20 +1072,20 @@ std::list<std::string> GlobalTransition::getCommonEvents(const NodeSet<std::stri } } } - + // from the set of event names, remove those that are prefixes for (std::list<std::string>::iterator outerEventNameIter = prefixes.begin(); - outerEventNameIter != prefixes.end(); - outerEventNameIter++) { + outerEventNameIter != prefixes.end(); + outerEventNameIter++) { for (std::list<std::string>::iterator innerEventNameIter = prefixes.begin(); - innerEventNameIter != prefixes.end(); - innerEventNameIter++) { + innerEventNameIter != prefixes.end(); + innerEventNameIter++) { if (!iequals(*outerEventNameIter, *innerEventNameIter) && Interpreter::nameMatch(*outerEventNameIter, *innerEventNameIter)) { goto IS_PREFIX; } } longestPrefixes.push_back(*outerEventNameIter); - IS_PREFIX: +IS_PREFIX: ; } return longestPrefixes; diff --git a/src/uscxml/transform/ChartToFSM.h b/src/uscxml/transform/ChartToFSM.h index 14ec4e7..80f532a 100644 --- a/src/uscxml/transform/ChartToFSM.h +++ b/src/uscxml/transform/ChartToFSM.h @@ -37,21 +37,21 @@ public: GlobalState() {} GlobalState(const Arabica::XPath::NodeSet<std::string>& activeStates, - const Arabica::XPath::NodeSet<std::string>& alreadyEnteredStates, // we need to remember for binding=late - const std::map<std::string, Arabica::XPath::NodeSet<std::string> >& historyStates); - + const Arabica::XPath::NodeSet<std::string>& alreadyEnteredStates, // we need to remember for binding=late + const std::map<std::string, Arabica::XPath::NodeSet<std::string> >& historyStates); + Arabica::XPath::NodeSet<std::string> activeStates; Arabica::XPath::NodeSet<std::string> alreadyEnteredStates; std::map<std::string, Arabica::XPath::NodeSet<std::string> > historyStates; - + std::map<std::string, GlobalTransition*> incoming; std::map<std::string, GlobalTransition*> outgoing; std::string stateId; - + bool isFinal; }; - + class GlobalTransition { public: class Action { @@ -64,24 +64,24 @@ public: Arabica::DOM::Node<std::string> invoke; Arabica::DOM::Node<std::string> uninvoke; }; - + GlobalTransition(const Arabica::XPath::NodeSet<std::string>& transitions, DataModel dataModel); - + bool isValid; // constructor will determine, calling code will delete if not bool isEventless; // whether or not all our transitions are eventless bool isTargetless; // whether or not all our transitions are eventless bool isSubset; // there is a superset to this set - + std::vector<long> firstElemPerLevel; std::vector<long> nrElemPerLevel; std::vector<long> prioPerLevel; - + Arabica::XPath::NodeSet<std::string> transitions; // constituting transitions 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 - + // executable content we gathered when we took the transition std::list<Action> actions; @@ -90,19 +90,21 @@ public: Arabica::XPath::NodeSet<std::string> invoke; Arabica::XPath::NodeSet<std::string> uninvoke; - + std::string transitionId; std::string source; std::string destination; - + protected: - std::list<std::string> getCommonEvents(const Arabica::XPath::NodeSet<std::string>& transitions); + std::list<std::string> getCommonEvents(const Arabica::XPath::NodeSet<std::string>& transitions); }; - + class FlatteningInterpreter : public InterpreterDraft6, public InterpreterMonitor { public: FlatteningInterpreter(const Arabica::DOM::Document<std::string>& doc); - Arabica::DOM::Document<std::string>& getDocument(); // overwrite to return flat FSM + virtual ~FlatteningInterpreter(); + + Arabica::DOM::Document<std::string> getDocument() const; // overwrite to return flat FSM void interpret(); protected: @@ -131,22 +133,22 @@ protected: void weightTransitions(); void createDocument(); - Arabica::DOM::Node<std::string> globalStateToNode(GlobalState* globalState, const std::string& xmlNs); - Arabica::DOM::Node<std::string> globalTransitionToNode(GlobalTransition* globalTransition, const std::string& xmlNs); + Arabica::DOM::Node<std::string> globalStateToNode(GlobalState* globalState); + Arabica::DOM::Node<std::string> globalTransitionToNode(GlobalTransition* globalTransition); GlobalState* _start; GlobalTransition* _currGlobalTransition; - + int maxDepth; int maxOrder; - + Arabica::DOM::Document<std::string> _flatDoc; std::map<std::string, GlobalState*> _globalConf; }; - + class ChartToFSM { public: - static Arabica::DOM::Document<std::string> flatten(const Arabica::DOM::Document<std::string>& doc, const std::map<std::string, std::string>& nameSpaceInfo); + static Interpreter flatten(const Interpreter& other); }; } diff --git a/src/uscxml/transform/FSMToPromela.cpp b/src/uscxml/transform/FSMToPromela.cpp index 0c61900..dc3b581 100644 --- a/src/uscxml/transform/FSMToPromela.cpp +++ b/src/uscxml/transform/FSMToPromela.cpp @@ -19,10 +19,13 @@ #include "uscxml/transform/ChartToFSM.h" #include "uscxml/transform/FSMToPromela.h" +#include "uscxml/plugins/datamodel/promela/PromelaParser.h" #include <DOM/io/Stream.hpp> #include <iostream> #include "uscxml/UUID.h" #include <math.h> +#include <boost/algorithm/string.hpp> +#include <glog/logging.h> namespace uscxml { @@ -30,47 +33,696 @@ using namespace Arabica::DOM; using namespace Arabica::XPath; void FSMToPromela::writeProgram(std::ostream& stream, - const Arabica::DOM::Document<std::string>& doc, - const std::map<std::string, std::string>& namespaceInfo) { + const Interpreter& interpreter) { + FSMToPromela promelaWriter; + interpreter.getImpl()->copyTo(&promelaWriter); + promelaWriter.writeProgram(stream); +} + +FSMToPromela::FSMToPromela() : _eventTrie(".") { +} + +void FSMToPromela::writeEvents(std::ostream& stream) { + std::list<TrieNode*> eventNames = _eventTrie.getWordsWithPrefix(""); + std::list<TrieNode*>::iterator eventIter = eventNames.begin(); + stream << "// event name identifiers" << std::endl; + while(eventIter != eventNames.end()) { + stream << "#define " << "e" << (*eventIter)->identifier << " " << (*eventIter)->identifier; + stream << " // from \"" << (*eventIter)->value << "\"" << std::endl; + eventIter++; + } +} + +void FSMToPromela::writeStates(std::ostream& stream) { + stream << "// state name identifiers" << std::endl; + for (int i = 0; i < _globalStates.size(); i++) { + stream << "#define " << "s" << i << " " << i; + stream << " // from \"" << ATTR(_globalStates[i], "id") << "\"" << std::endl; + } + +} + +Arabica::XPath::NodeSet<std::string> FSMToPromela::getTransientContent(const Arabica::DOM::Node<std::string>& state) { + Arabica::XPath::NodeSet<std::string> content; + Arabica::DOM::Node<std::string> currState = state; + for (;;) { + if (!HAS_ATTR(currState, "transient") || !DOMUtils::attributeIsTrue(ATTR(currState, "transient"))) + break; + content.push_back(filterChildElements(_nsInfo.xmlNSPrefix + "invoke", currState)); + content.push_back(filterChildElements(_nsInfo.xmlNSPrefix + "onentry", currState)); + content.push_back(filterChildElements(_nsInfo.xmlNSPrefix + "onexit", currState)); + NodeSet<std::string> transitions = filterChildElements(_nsInfo.xmlNSPrefix + "transition", currState); + currState = _states[ATTR(transitions[0], "target")]; + } + + return content; +} + +Node<std::string> FSMToPromela::getUltimateTarget(const Arabica::DOM::Node<std::string>& transition) { + Arabica::DOM::Node<std::string> currState = _states[ATTR(transition, "target")]; + + for (;;) { + if (!HAS_ATTR(currState, "transient") || !DOMUtils::attributeIsTrue(ATTR(currState, "transient"))) + return currState; + NodeSet<std::string> transitions = filterChildElements(_nsInfo.xmlNSPrefix + "transition", currState); + currState = _states[ATTR(transitions[0], "target")]; + } +} + +void FSMToPromela::writeInlineComment(std::ostream& stream, const Arabica::DOM::Node<std::string>& node) { + if (node.getNodeType() != Node_base::COMMENT_NODE) + return; + + std::string comment = node.getNodeValue(); + boost::trim(comment); + if (!boost::starts_with(comment, "promela-inline:")) + return; + + std::stringstream ssLine(comment); + std::string line; + std::getline(ssLine, line); // consume first line + while(std::getline(ssLine, line)) { + if (line.length() == 0) + continue; + stream << line; + } +} + +void FSMToPromela::writeExecutableContent(std::ostream& stream, const Arabica::DOM::Node<std::string>& node, int indent) { + + std::string padding; + for (int i = 0; i < indent; i++) { + padding += " "; + } + + if (node.getNodeType() == Node_base::COMMENT_NODE) { + std::string comment = node.getNodeValue(); + boost::trim(comment); + std::stringstream inlinePromela; + if (!boost::starts_with(comment, "promela-inline:")) + return; + std::stringstream ssLine(comment); + std::string line; + std::getline(ssLine, line); // consume first line + while(std::getline(ssLine, line)) { + if (line.length() == 0) + continue; + inlinePromela << line << std::endl; + } + stream << padding << "skip;" << std::endl; + stream << beautifyIndentation(inlinePromela.str(), indent) << std::endl; + } + + if (node.getNodeType() != Node_base::ELEMENT_NODE) + return; + + if (false) { + } else if(TAGNAME(node) == "state") { + if (HAS_ATTR(node, "transient") && DOMUtils::attributeIsTrue(ATTR(node, "transient"))) { + Arabica::XPath::NodeSet<std::string> execContent = getTransientContent(node); + for (int i = 0; i < execContent.size(); i++) { + writeExecutableContent(stream, execContent[i], indent); + } + } else { + Arabica::DOM::Node<std::string> child = node.getFirstChild(); + while(child) { + writeExecutableContent(stream, child, indent); + child = child.getNextSibling(); + } + } + } else if(TAGNAME(node) == "transition") { + stream << "t" << _transitions[node] << ":" << std::endl; + + // check for special promela labels + PromelaInlines promInls = getInlinePromela(getTransientContent(_states[ATTR(node, "target")]), true); + + if (promInls.hasAcceptLabel) + stream << padding << "acceptLabelT" << _transitions[node] << ":" << std::endl; + if (promInls.hasEndLabel) + stream << padding << "endLabelT" << _transitions[node] << ":" << std::endl; + if (promInls.hasProgressLabel) + stream << padding << "progressLabelT" << _transitions[node] << ":" << std::endl; + + stream << padding << "atomic {" << std::endl; + writeExecutableContent(stream, _states[ATTR(node, "target")], indent+1); + stream << padding << " skip;" << std::endl; + + Node<std::string> newState = getUltimateTarget(node); + for (int i = 0; i < _globalStates.size(); i++) { + if (newState != _globalStates[i]) + continue; + stream << padding << " s = s" << i << ";" << std::endl; + } + + stream << padding << "}" << std::endl; + if (isFinal(newState)) { + stream << padding << "goto terminate;" << std::endl; + } else { + stream << padding << "goto nextStep;" << std::endl; + } + + } else if(TAGNAME(node) == "onentry" || TAGNAME(node) == "onexit") { + Arabica::DOM::Node<std::string> child = node.getFirstChild(); + while(child) { + writeExecutableContent(stream, child, indent); + child = child.getNextSibling(); + } + + } else if(TAGNAME(node) == "script") { + NodeSet<std::string> scriptText = filterChildType(Node_base::TEXT_NODE, node, true); + for (int i = 0; i < scriptText.size(); i++) { + stream << beautifyIndentation(scriptText[i].getNodeValue(), indent) << std::endl; + } + + } else if(TAGNAME(node) == "log") { + // ignore + + } else if(TAGNAME(node) == "foreach") { + if (HAS_ATTR(node, "index")) + stream << padding << ATTR(node, "index") << " = 0;" << std::endl; + stream << padding << "for (" << ATTR(node, "item") << " in " << ATTR(node, "array") << ") {" << std::endl; + Arabica::DOM::Node<std::string> child = node.getFirstChild(); + while(child) { + writeExecutableContent(stream, child, indent + 1); + child = child.getNextSibling(); + } + if (HAS_ATTR(node, "index")) + stream << padding << " " << ATTR(node, "index") << "++;" << std::endl; + stream << padding << "}" << std::endl; + + } else if(TAGNAME(node) == "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(node) == "raise") { + TrieNode* trieNode = _eventTrie.getNodeWithPrefix(ATTR(node, "event")); + stream << padding << "iQ!e" << trieNode->identifier << ";" << std::endl; + } else if(TAGNAME(node) == "invoke") { + stream << padding << "run " << ATTR(node, "invokeid") << "EventSource();" << std::endl; + } else if(TAGNAME(node) == "uninvoke") { + stream << padding << ATTR(node, "invokeid") << "EventSourceDone" << "= 1;" << std::endl; + } else { + + std::cerr << "'" << TAGNAME(node) << "'" << std::endl << node << std::endl; + assert(false); + } + +} + +PromelaInlines FSMToPromela::getInlinePromela(const Arabica::XPath::NodeSet<std::string>& elements, bool recurse) { + PromelaInlines prom; + + if (elements.size() == 0) + return prom; + + Arabica::XPath::NodeSet<std::string> comments = filterChildType(Node_base::COMMENT_NODE, elements, recurse); + for (int i = 0; i < comments.size(); i++) { + std::stringstream ssLine(comments[i].getNodeValue()); + std::string line; + + bool isInPromelaCode = false; + PromelaInline promInl; + + while(std::getline(ssLine, line)) { + std::string trimLine = boost::trim_copy(line); + if (line.length() == 0) + continue; + if (false) { + } else if (boost::starts_with(trimLine, "promela-progress")) { + prom.hasProgressLabel = true; + if (isInPromelaCode) { + prom.inlines.push_back(promInl); + isInPromelaCode = false; + } + promInl.type = PromelaInline::PROMELA_PROGRESS_LABEL; + promInl.content = line; + prom.inlines.push_back(promInl); + } else if (boost::starts_with(trimLine, "promela-accept")) { + prom.hasAcceptLabel = true; + if (isInPromelaCode) { + prom.inlines.push_back(promInl); + isInPromelaCode = false; + } + promInl.type = PromelaInline::PROMELA_ACCEPT_LABEL; + promInl.content = line; + prom.inlines.push_back(promInl); + } else if (boost::starts_with(trimLine, "promela-end")) { + prom.hasEndLabel = true; + if (isInPromelaCode) { + prom.inlines.push_back(promInl); + isInPromelaCode = false; + } + promInl.type = PromelaInline::PROMELA_END_LABEL; + promInl.content = line; + prom.inlines.push_back(promInl); + } else if (boost::starts_with(trimLine, "promela-inline")) { + prom.hasCode = true; + isInPromelaCode = true; + promInl.type = PromelaInline::PROMELA_CODE; + } else if (isInPromelaCode) { + promInl.content += line; + } + } + // inline code ends with comment + if (isInPromelaCode) { + prom.inlines.push_back(promInl); + } + } + return prom; +} + +void FSMToPromela::writeIfBlock(std::ostream& stream, const Arabica::XPath::NodeSet<std::string>& condChain, int indent) { + if (condChain.size() == 0) + return; + + std::string padding; + for (int i = 0; i < indent; i++) { + padding += " "; + } + + bool noNext = condChain.size() == 1; + bool nextIsElse = false; + if (condChain.size() > 1) { + if (TAGNAME(condChain[1]) == "else") { + nextIsElse = true; + } + } + + Node<std::string> ifNode = condChain[0]; + + stream << padding << "if" << std::endl; + // we need to nest the elseifs to resolve promela if semantics + stream << padding << ":: (" << ATTR(ifNode, "cond") << ") -> {" << std::endl; + + Arabica::DOM::Node<std::string> child; + if (TAGNAME(ifNode) == "if") { + child = ifNode.getFirstChild(); + } else { + child = ifNode.getNextSibling(); + } + while(child) { + if (child.getNodeType() == Node_base::ELEMENT_NODE) { + if (TAGNAME(child) == "elseif" || TAGNAME(child) == "else") + break; + } + writeExecutableContent(stream, child, indent + 1); + child = child.getNextSibling(); + } + stream << padding << "}" << std::endl; + stream << padding << ":: else -> "; + + if (nextIsElse) { + child = condChain[1].getNextSibling(); + stream << "{" << std::endl; + while(child) { + writeExecutableContent(stream, child, indent + 1); + child = child.getNextSibling(); + } + stream << padding << "}" << std::endl; + + } else if (noNext) { + stream << "skip;" << std::endl; + } else { + stream << "{" << std::endl; + + Arabica::XPath::NodeSet<std::string> cdrCondChain; + for (int i = 1; i < condChain.size(); i++) { + cdrCondChain.push_back(condChain[i]); + } + writeIfBlock(stream, cdrCondChain, indent + 1); + stream << padding << "}" << std::endl; + + } + + stream << padding << "fi;" << std::endl; + +} + +std::string FSMToPromela::beautifyIndentation(const std::string& code, int indent) { + + std::string padding; + for (int i = 0; i < indent; i++) { + padding += " "; + } + + // remove topmost indentation from every line and reindent + std::stringstream beautifiedSS; + + std::string initialIndent; + bool gotIndent = false; + bool isFirstLine = true; + std::stringstream ssLine(code); + std::string line; + + while(std::getline(ssLine, line)) { + size_t firstChar = line.find_first_not_of(" \t\r\n"); + if (firstChar != std::string::npos) { + if (!gotIndent) { + initialIndent = line.substr(0, firstChar); + gotIndent = true; + } + beautifiedSS << (isFirstLine ? "" : "\n") << padding << boost::replace_first_copy(line, initialIndent, ""); + isFirstLine = false; + } + } + + return beautifiedSS.str(); +} + +void FSMToPromela::writeDeclarations(std::ostream& stream) { + + // get all data elements + NodeSet<std::string> datas = _xpath.evaluate("//" + _nsInfo.xpathPrefix + "data", _scxml).asNodeSet(); + NodeSet<std::string> dataText = filterChildType(Node_base::TEXT_NODE, datas, true); + + // write their text content + stream << "// datamodel variables" << std::endl; + for (int i = 0; i < dataText.size(); i++) { + Node<std::string> data = dataText[i]; + stream << beautifyIndentation(data.getNodeValue()) << std::endl; + } + + stream << std::endl; + stream << "// global variables" << std::endl; + stream << "int e; /* current event */" << std::endl; + stream << "int s; /* current state */" << std::endl; + stream << "chan iQ = [100] of {int} /* internal queue */" << std::endl; + stream << "chan eQ = [100] of {int} /* external queue */" << std::endl; + + stream << std::endl; + stream << "// event sources" << std::endl; + if (_globalEventSource) + stream << "bool globalEventSourceDone;" << std::endl; + + std::map<std::string, PromelaEventSource>::iterator invIter = _invokers.begin(); + while(invIter != _invokers.end()) { + stream << "bool " << invIter->first << "EventSourceDone;" << std::endl; + stream << std::endl; + invIter++; + } + +} + +void FSMToPromela::writeEventSources(std::ostream& stream) { + if (_globalEventSource) + writeEventSource(stream, "global", _globalEventSource); + + std::map<std::string, PromelaEventSource>::iterator invIter = _invokers.begin(); + while(invIter != _invokers.end()) { + writeEventSource(stream, invIter->first, invIter->second); + invIter++; + } + +} + +void FSMToPromela::writeEventSource(std::ostream& stream, const std::string& name, const PromelaEventSource& source) { + stream << "proctype " << name << "EventSource() {" << std::endl; + stream << " " << name << "EventSourceDone = 0;" << std::endl; + stream << " " << name << "NewEvent:" << std::endl; + stream << " " << "if" << std::endl; + stream << " " << ":: " << name << "EventSourceDone -> skip;" << std::endl; + stream << " " << ":: else { " << std::endl; + stream << " " << " if" << std::endl; + stream << " " << " :: 1 -> " << "goto " << name << "NewEvent;" << std::endl; + + std::list<std::list<std::string> >::const_iterator seqIter = source.sequences.begin(); + while(seqIter != source.sequences.end()) { + stream << " " << ":: "; + std::list<std::string>::const_iterator evIter = seqIter->begin(); + while(evIter != seqIter->end()) { + TrieNode* node = _eventTrie.getNodeWithPrefix(*evIter); + stream << "eQ!" << node->identifier << "; "; + evIter++; + } + stream << "goto " << name << "NewEvent;" << std::endl; + seqIter++; + } + stream << " " << " fi" << std::endl; + stream << " " << "}" << std::endl; + stream << " " << "fi" << std::endl; + stream << "}" << std::endl; +} + + +void FSMToPromela::writeFSM(std::ostream& stream) { + NodeSet<std::string> transitions; + + stream << "proctype step() {" << std::endl; + // write initial transition + transitions = filterChildElements(_nsInfo.xmlNSPrefix + "transition", _startState); + assert(transitions.size() == 1); + stream << " // transition's executable content" << std::endl; + writeExecutableContent(stream, transitions[0], 1); + + for (int i = 0; i < _globalStates.size(); i++) { + if (_globalStates[i] == _startState) + continue; + NodeSet<std::string> transitions = filterChildElements(_nsInfo.xmlNSPrefix + "transition", _globalStates[i]); + for (int j = 0; j < transitions.size(); j++) { + writeExecutableContent(stream, transitions[j], 1); + } + } + + stream << std::endl; + stream << "nextStep: /* pop an event */" << std::endl; + stream << " if" << std::endl; + stream << " :: len(iQ) != 0 -> iQ ? e /* from internal queue */" << std::endl; + stream << " :: else -> eQ ? e /* from external queue */" << std::endl; + stream << " fi;" << std::endl; + stream << " /* event dispatching per state */" << std::endl; + stream << " if" << std::endl; + + writeEventDispatching(stream); + + stream << " :: else -> goto nextStep;" << std::endl; + stream << " fi;" << std::endl; + stream << "terminate: skip;" << std::endl; + + // stop all event sources + if (_globalEventSource) + stream << " globalEventSourceDone = 1;" << std::endl; + + std::map<std::string, PromelaEventSource>::iterator invIter = _invokers.begin(); + while(invIter != _invokers.end()) { + stream << " " << invIter->first << "EventSourceDone = 1;" << std::endl; + invIter++; + } + + + stream << "}" << std::endl; +} + +void FSMToPromela::writeEventDispatching(std::ostream& stream) { + for (int i = 0; i < _globalStates.size(); i++) { + if (_globalStates[i] == _startState) + continue; + + stream << " :: (s == s" << i << ") -> {" << std::endl; + NodeSet<std::string> transitions = filterChildElements(_nsInfo.xmlNSPrefix + "transition", _globalStates[i]); + writeDispatchingBlock(stream, transitions, 2); + stream << " goto nextStep;" << std::endl; + stream << " }" << std::endl; + } } -FSMToPromela::FSMToPromela(const Arabica::DOM::Document<std::string>& doc, - const std::map<std::string, std::string>& namespaceInfo) { +void FSMToPromela::writeDispatchingBlock(std::ostream& stream, const Arabica::XPath::NodeSet<std::string>& transChain, int indent) { + if (transChain.size() == 0) + return; - std::map<std::string, std::string>::const_iterator nsIter = namespaceInfo.begin(); - while(nsIter != namespaceInfo.end()) { - std::string uri = nsIter->first; - std::string prefix = nsIter->second; - if (iequals(uri, "http://www.w3.org/2005/07/scxml")) { - _nsURL = uri; - if (prefix.size() == 0) { - _xpathPrefix = "scxml:"; - _nsContext.addNamespaceDeclaration(uri, "scxml"); - _nsToPrefix[uri] = "scxml"; - } else { - _xpathPrefix = prefix + ":"; - _xmlNSPrefix = _xpathPrefix; - _nsContext.addNamespaceDeclaration(uri, prefix); - _nsToPrefix[uri] = prefix; + std::string padding; + for (int i = 0; i < indent; i++) { + padding += " "; + } + + stream << padding << "if" << std::endl; + stream << padding << ":: ((0"; + + Node<std::string> currTrans = transChain[0]; + std::string eventDesc = ATTR(currTrans, "event"); + if (boost::ends_with(eventDesc, "*")) + eventDesc = eventDesc.substr(0, eventDesc.size() - 1); + if (boost::ends_with(eventDesc, ".")) + eventDesc = eventDesc.substr(0, eventDesc.size() - 1); + + if (eventDesc.size() == 0) { + stream << " || 1"; + } else { + std::list<TrieNode*> trieNodes = _eventTrie.getWordsWithPrefix(eventDesc); + + std::list<TrieNode*>::iterator trieIter = trieNodes.begin(); + while(trieIter != trieNodes.end()) { + stream << " || e == e" << (*trieIter)->identifier; + trieIter++; + } + } + + stream << ") && "; + stream << (HAS_ATTR(currTrans, "cond") ? ATTR(currTrans, "cond") : "1"); + stream << ") -> goto t" << _transitions[currTrans] << ";" << std::endl; +; + + stream << padding << ":: else {" << std::endl; + + Arabica::XPath::NodeSet<std::string> cdrTransChain; + for (int i = 1; i < transChain.size(); i++) { + cdrTransChain.push_back(transChain[i]); + } + writeDispatchingBlock(stream, cdrTransChain, indent + 1); + + stream << padding << " goto nextStep;" << std::endl; + stream << padding << "}" << std::endl; + stream << padding << "fi;" << std::endl; +} + + +void FSMToPromela::writeMain(std::ostream& stream) { + stream << std::endl; + stream << "init {" << std::endl; + if (_globalEventSource) + stream << " run globalEventSource();" << std::endl; + stream << " run step();" << std::endl; + stream << "}" << std::endl; + +} + +void FSMToPromela::initNodes() { + // get all states + NodeSet<std::string> states = filterChildElements(_nsInfo.xmlNSPrefix + "state", _scxml); + for (int i = 0; i < states.size(); i++) { + _states[ATTR(states[i], "id")] = states[i]; + if (HAS_ATTR(states[i], "transient") && DOMUtils::attributeIsTrue(ATTR(states[i], "transient"))) + continue; + _globalStates.push_back(states[i]); + } + _startState = _states[ATTR(_scxml, "initial")]; + + // initialize event trie with all events that might occur + NodeSet<std::string> internalEventNames; + internalEventNames.push_back(_xpath.evaluate("//" + _nsInfo.xpathPrefix + "transition", _scxml).asNodeSet()); + internalEventNames.push_back(_xpath.evaluate("//" + _nsInfo.xpathPrefix + "raise", _scxml).asNodeSet()); + internalEventNames.push_back(_xpath.evaluate("//" + _nsInfo.xpathPrefix + "send", _scxml).asNodeSet()); + + for (int i = 0; i < internalEventNames.size(); i++) { + if (HAS_ATTR(internalEventNames[i], "event")) { + std::string eventNames = ATTR(internalEventNames[i], "event"); + std::list<std::string> events = tokenizeIdRefs(eventNames); + for (std::list<std::string>::iterator eventIter = events.begin(); + eventIter != events.end(); eventIter++) { + std::string eventName = *eventIter; + if (boost::ends_with(eventName, "*")) + eventName = eventName.substr(0, eventName.size() - 1); + if (boost::ends_with(eventName, ".")) + eventName = eventName.substr(0, eventName.size() - 1); + _eventTrie.addWord(eventName); + } + } + } + + // external event names from comments + NodeSet<std::string> promelaEventSourceComments; + NodeSet<std::string> invokers = _xpath.evaluate("//" + _nsInfo.xpathPrefix + "invoke", _scxml).asNodeSet(); + promelaEventSourceComments.push_back(filterChildType(Node_base::COMMENT_NODE, invokers, true)); // comments in invoke elements + promelaEventSourceComments.push_back(filterChildType(Node_base::COMMENT_NODE, _scxml, false)); // comments in scxml element + + for (int i = 0; i < promelaEventSourceComments.size(); i++) { + std::string comment = promelaEventSourceComments[i].getNodeValue(); + boost::trim(comment); + if (!boost::starts_with(comment, "promela-event-source:")) + continue; + PromelaEventSource* eventSource = NULL; + if (false) { + } else if (TAGNAME(promelaEventSourceComments[i].getParentNode()) == "scxml") { + eventSource = &_globalEventSource; + } else if (TAGNAME(promelaEventSourceComments[i].getParentNode()) == "invoke") { + if (!HAS_ATTR(promelaEventSourceComments[i].getParentNode(), "invokeid")) { + Element<std::string> invoker = Element<std::string>(promelaEventSourceComments[i].getParentNode()); + invoker.setAttribute("invokeid", "invoker" + toStr(_invokers.size())); } + std::string invokeId = ATTR(promelaEventSourceComments[i].getParentNode(), "invokeid"); + eventSource = &_invokers[invokeId]; } else { - _nsContext.addNamespaceDeclaration(uri, prefix); - _nsToPrefix[uri] = prefix; + assert(false); + } + if (!eventSource) + continue; + std::stringstream ssLine(comment); + std::string line; + std::getline(ssLine, line); // consume first line + while(std::getline(ssLine, line)) { + if (line.length() == 0) + continue; + std::list<std::string> currSeq; + + std::stringstream ssToken(line); + std::string token; + while(std::getline(ssToken, token, ' ')) { + if (token.length() == 0) + continue; + currSeq.push_back(token); + _eventTrie.addWord(token); + } + eventSource->sequences.push_back(currSeq); } - nsIter++; } - _xpath.setNamespaceContext(_nsContext); + + // enumerate transitions + NodeSet<std::string> transitions = filterChildElements(_nsInfo.xmlNSPrefix + "transition", _scxml, true); + int index = 0; + for (int i = 0; i < transitions.size(); i++) { + _transitions[transitions[i]] = index++; + } +} - _document = doc; - NodeList<std::string> scxmls = _document.getElementsByTagNameNS(_nsURL, "scxml"); - if (scxmls.getLength() > 0) { - _scxml = (Arabica::DOM::Element<std::string>)scxmls.item(0); +void PromelaEventSource::dump() { + std::list<std::list<std::string> >::iterator outerIter = sequences.begin(); + while(outerIter != sequences.end()) { + std::list<std::string>::iterator innerIter = outerIter->begin(); + while(innerIter != outerIter->end()) { + std::cout << *innerIter << " "; + innerIter++; + } + std::cout << std::endl; + outerIter++; } } void FSMToPromela::writeProgram(std::ostream& stream) { - stream << "foo"; + + if (!HAS_ATTR(_scxml, "flat") || !DOMUtils::attributeIsTrue(ATTR(_scxml, "flat"))) { + LOG(ERROR) << "Given SCXML document was not flattened"; + return; + } + + if (!HAS_ATTR(_scxml, "datamodel") || ATTR(_scxml, "datamodel") != "promela") { + LOG(ERROR) << "Can only convert SCXML documents with \"promela\" datamodel"; + return; + } + + if (HAS_ATTR(_scxml, "binding") && ATTR(_scxml, "binding") != "early") { + LOG(ERROR) << "Can only convert for early data bindings"; + return; + } + + initNodes(); + + writeEvents(stream); + stream << std::endl; + writeStates(stream); + stream << std::endl; + writeDeclarations(stream); + stream << std::endl; + writeEventSources(stream); + stream << std::endl; + writeFSM(stream); + stream << std::endl; + writeMain(stream); + stream << std::endl; + } }
\ No newline at end of file diff --git a/src/uscxml/transform/FSMToPromela.h b/src/uscxml/transform/FSMToPromela.h index c3324bb..adb0f6a 100644 --- a/src/uscxml/transform/FSMToPromela.h +++ b/src/uscxml/transform/FSMToPromela.h @@ -21,37 +21,90 @@ #define FSMTOPROMELA_H_RP48RFDJ #include "uscxml/DOMUtils.h" +#include "uscxml/util/Trie.h" + #include <DOM/Document.hpp> #include <DOM/Node.hpp> #include <XPath/XPath.hpp> #include <ostream> namespace uscxml { + +class PromelaInline { +public: + enum PromelaInlineType { + PROMELA_CODE, + PROMELA_EVENT_SOURCE, + PROMELA_PROGRESS_LABEL, + PROMELA_ACCEPT_LABEL, + PROMELA_END_LABEL + }; -class FSMToPromela { + std::string content; + PromelaInlineType type; +}; + +class PromelaInlines { +public: + PromelaInlines() : hasProgressLabel(false), hasAcceptLabel(false), hasEndLabel(false), hasEventSource(false), hasCode(false) {} + + std::list<PromelaInline> inlines; + bool hasProgressLabel; + bool hasAcceptLabel; + bool hasEndLabel; + bool hasEventSource; + bool hasCode; +}; + +struct PromelaEventSource { + std::list<std::list<std::string> > sequences; + void dump(); + operator bool() { + return sequences.size() > 0; + } +}; + +class FSMToPromela : public InterpreterDraft6 { public: static void writeProgram(std::ostream& stream, - const Arabica::DOM::Document<std::string>& doc, - const std::map<std::string, std::string>& namespaceInfo); + const Interpreter& interpreter); protected: - FSMToPromela(const Arabica::DOM::Document<std::string>& doc, - const std::map<std::string, std::string>& namespaceInfo); - + FSMToPromela(); void writeProgram(std::ostream& stream); + + void initNodes(); + + void writeEvents(std::ostream& stream); + void writeStates(std::ostream& stream); + void writeDeclarations(std::ostream& stream); + void writeEventSources(std::ostream& stream); + void writeEventSource(std::ostream& stream, const std::string& name, const PromelaEventSource& source); + void writeExecutableContent(std::ostream& stream, const Arabica::DOM::Node<std::string>& node, int indent = 0); + void writeInlineComment(std::ostream& stream, const Arabica::DOM::Node<std::string>& node); + void writeFSM(std::ostream& stream); + void writeEventDispatching(std::ostream& stream); + void writeMain(std::ostream& stream); - Arabica::DOM::Document<std::string> _document; - Arabica::DOM::Node<std::string> _scxml; - Arabica::XPath::XPath<std::string> _xpath; - Arabica::XPath::StandardNamespaceContext<std::string> _nsContext; - std::string _xmlNSPrefix; // the actual prefix for elements in the xml file - std::string _xpathPrefix; // prefix mapped for xpath, "scxml" is _xmlNSPrefix is empty but _nsURL set - std::string _nsURL; // ough to be "http://www.w3.org/2005/07/scxml" - std::map<std::string, std::string> _nsToPrefix; - std::map<std::string, std::string> _nameSpaceInfo; + void writeIfBlock(std::ostream& stream, const Arabica::XPath::NodeSet<std::string>& condChain, int indent = 0); + void writeDispatchingBlock(std::ostream& stream, const Arabica::XPath::NodeSet<std::string>& transChain, int indent = 0); -}; + std::string beautifyIndentation(const std::string& code, int indent = 0); + + Arabica::XPath::NodeSet<std::string> getTransientContent(const Arabica::DOM::Node<std::string>& state); + Arabica::DOM::Node<std::string> getUltimateTarget(const Arabica::DOM::Node<std::string>& transition); + PromelaInlines getInlinePromela(const Arabica::XPath::NodeSet<std::string>& elements, bool recurse = false); + Trie _eventTrie; + Arabica::XPath::NodeSet<std::string> _globalStates; + Arabica::DOM::Node<std::string> _startState; + std::map<std::string, Arabica::DOM::Node<std::string> > _states; + std::map<Arabica::DOM::Node<std::string>, int> _transitions; + + std::map<std::string, PromelaEventSource> _invokers; + PromelaEventSource _globalEventSource; +}; + } #endif /* end of include guard: FSMTOPROMELA_H_RP48RFDJ */ diff --git a/src/uscxml/util/Trie.cpp b/src/uscxml/util/Trie.cpp new file mode 100644 index 0000000..ebcc3ef --- /dev/null +++ b/src/uscxml/util/Trie.cpp @@ -0,0 +1,165 @@ +/** + * @file + * @author 2012-2014 Stefan Radomski (stefan.radomski@cs.tu-darmstadt.de) + * @copyright Simplified BSD + * + * @cond + * This program is free software: you can redistribute it and/or modify + * it under the terms of the FreeBSD license as published by the FreeBSD + * project. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * You should have received a copy of the FreeBSD license along with this + * program. If not, see <http://www.opensource.org/licenses/bsd-license>. + * @endcond + */ + +#include "Trie.h" +#include <iostream> + +namespace uscxml { + +Trie::Trie() { + root = new TrieNode(); + lastIdentifier = 0; +} + +Trie::Trie(const std::string& seperator) : seperator(seperator) { + root = new TrieNode(); + lastIdentifier = 0; +} + +Trie::~Trie() { + delete root; +} + +TrieNode::TrieNode() : hasWord(false) {} + +TrieNode::~TrieNode() { + std::map<std::string, TrieNode*>::iterator childIter = childs.begin(); + while(childIter != childs.end()) { + delete childIter->second; + childIter++; + } +} + +size_t Trie::getNextToken(const std::string& word, size_t offset, std::string& token) { + if (offset == std::string::npos || offset >= word.length()) { + token = ""; + return std::string::npos; + } + if (seperator.size() > 0) { + size_t sepPos = word.find(seperator, offset); + if (sepPos == offset) // starts with a seperator + return getNextToken(word, offset + seperator.length(), token); + if (sepPos == std::string::npos) { + token = word.substr(offset, word.length() - offset); + } else { + token = word.substr(offset, sepPos - offset); + sepPos += seperator.length(); + } + return sepPos; + } + token = word[offset]; + return offset + 1; +} + +void Trie::addWord(const std::string& word) { + TrieNode* currNode = root; + + std::string prefix; + size_t offset = 0; + + for(;;) { + offset = getNextToken(word, offset, prefix); + + if (prefix.size() > 0) { + if (currNode->childs.find(prefix) == currNode->childs.end()) + currNode->childs[prefix] = new TrieNode(); + currNode = currNode->childs[prefix]; + } + + if (offset == std::string::npos) + break; + } + if (!currNode->hasWord) { + currNode->identifier = lastIdentifier++; + currNode->value = word; + currNode->hasWord = true; + } +} + +TrieNode* Trie::getNodeWithPrefix(const std::string& prefix) { + std::string token; + size_t offset = 0; + + TrieNode* currNode = root; + + for(;;) { + offset = getNextToken(prefix, offset, token); + if (currNode->childs.find(token) == currNode->childs.end()) { + if (token.size() > 0) + currNode = NULL; + break; + } else { + currNode = currNode->childs[token]; + } + } + return currNode; +} + +std::list<TrieNode*> Trie::getWordsWithPrefix(const std::string& prefix) { + std::list<TrieNode*> nodes; + TrieNode* prefixNode = getNodeWithPrefix(prefix); + + if (prefixNode) { + nodes = getChildsWithWords(prefixNode); + } + + return nodes; +} + +std::list<TrieNode*> Trie::getChildsWithWords(TrieNode* node) { + std::list<TrieNode*> nodes; + if (node->hasWord) { + nodes.push_back(node); + } + + std::map<std::string, TrieNode*>::iterator childIter = node->childs.begin(); + while(childIter != node->childs.end()) { + std::list<TrieNode*> otherChilds = getChildsWithWords(childIter->second); + nodes.merge(otherChilds); + childIter++; + } + + return nodes; +} + +void TrieNode::dump(int indent) { + std::string padding; + for (int i = 0; i < indent; i++) { + padding += " "; + } + + std::map<std::string, TrieNode*>::iterator childIter = childs.begin(); + while(childIter != childs.end()) { + std::cout << padding << childIter->first; + if (childIter->second->hasWord) { + std::cout << " (word)"; + } + std::cout << std::endl; + childIter->second->dump(indent + 1); + childIter++; + } +} + +void Trie::dump() { + if (root->hasWord) + std::cout << "(word)" << std::endl; + root->dump(); +} + +}
\ No newline at end of file diff --git a/src/uscxml/util/Trie.h b/src/uscxml/util/Trie.h new file mode 100644 index 0000000..5c2d14e --- /dev/null +++ b/src/uscxml/util/Trie.h @@ -0,0 +1,61 @@ +/** + * @file + * @author 2012-2014 Stefan Radomski (stefan.radomski@cs.tu-darmstadt.de) + * @copyright Simplified BSD + * + * @cond + * This program is free software: you can redistribute it and/or modify + * it under the terms of the FreeBSD license as published by the FreeBSD + * project. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * You should have received a copy of the FreeBSD license along with this + * program. If not, see <http://www.opensource.org/licenses/bsd-license>. + * @endcond + */ + +#ifndef TRIE_H_UZMQRBO5 +#define TRIE_H_UZMQRBO5 + +#include <string> +#include <map> +#include <list> + +namespace uscxml { + +struct TrieNode { + TrieNode(); + virtual ~TrieNode(); + + bool hasWord; + int identifier; + std::string value; + std::map<std::string, TrieNode*> childs; + void dump(int indent = 0); +}; + +struct Trie { + Trie(); + Trie(const std::string& seperator); + virtual ~Trie(); + + void addWord(const std::string& word); + size_t getNextToken(const std::string& word, size_t offset, std::string& token); + + TrieNode* getNodeWithPrefix(const std::string& prefix); + std::list<TrieNode*> getWordsWithPrefix(const std::string& prefix); + std::list<TrieNode*> getChildsWithWords(TrieNode* node); + void dump(); + + TrieNode* root; + std::string seperator; + int lastIdentifier; +}; + +} + + +#endif /* end of include guard: TRIE_H_UZMQRBO5 */ |