void Debugger::afterCompletion(Interpreter& interpreter) { InterpreterImpl* impl = interpreter.getImpl().get(); std::shared_ptr<DebugSession> session = getSession(impl); if (!session) return; Data msg; msg.compound["replyType"] = Data("finished", Data::VERBATIM); pushData(session, msg); }
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.getImpl()->getSourceState(transition)); Arabica::XPath::NodeSet<std::string> targets = interpreter.getImpl()->getTargetStates(transition); for (size_t 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"); bp.transTargetId = ATTR(target, "id"); bp.subject = Breakpoint::TRANSITION; breakpoints.push_back(bp); } return breakpoints; }
void Debugger::handleTransition(Interpreter& interpreter, const XERCESC_NS::DOMElement* transition, Breakpoint::When when) { InterpreterImpl* impl = interpreter.getImpl().get(); std::shared_ptr<DebugSession> session = getSession(impl); if (!session) return; if (!session->_isRunning) return; Breakpoint breakpointTemplate; breakpointTemplate.when = when; std::list<Breakpoint> qualifiedBreakpoints = getQualifiedTransBreakpoints(impl, transition, breakpointTemplate); session->checkBreakpoints(qualifiedBreakpoints); }
void testDOMUtils() { const char* xml = "<scxml>" " <state doc=\"1\" post=\"1\">" " <transition doc=\"1\" post=\"1\" />" " </state>" " <state doc=\"2\" post=\"3\">" " <transition doc=\"2\" post=\"3\" />" " <state doc=\"3\" post=\"2\">" " <transition doc=\"2\" post=\"2\" />" " </state>" " </state>" " <final id=\"done\" />" "</scxml>"; size_t index = 1; Interpreter interpreter = Interpreter::fromXML(xml, ""); interpreter.step(); XERCESC_NS::DOMElement* scxml = interpreter.getImpl()->getDocument()->getDocumentElement(); { // postfix std::list<DOMElement*> result; DOMUtils::filterElementGeneric({ "state" }, result, scxml, DOMUtils::POSTFIX, true, true); index = 1; for (auto trans : result) { assert(HAS_ATTR(trans, X("post"))); std::cout << "post: " << ATTR(trans, X("post")) << std::endl; assert(ATTR(trans, X("post")) == toStr(index)); index++; } } { // document std::list<DOMElement*> result; DOMUtils::filterElementGeneric({ "state" }, result, scxml, DOMUtils::DOCUMENT, true, true); index = 1; for (auto trans : result) { assert(HAS_ATTR(trans, X("doc"))); std::cout << "doc: " << ATTR(trans, X("doc")) << std::endl; assert(ATTR(trans, X("doc")) == toStr(index)); index++; } } }
void Debugger::handleInvoke(Interpreter& interpreter, const XERCESC_NS::DOMElement* invokeElem, const std::string& invokeId, Breakpoint::When when, Breakpoint::Action action) { InterpreterImpl* impl = interpreter.getImpl().get(); std::shared_ptr<DebugSession> session = getSession(impl); if (!session) return; if (!session->_isRunning) return; Breakpoint breakpointTemplate; breakpointTemplate.when = when; breakpointTemplate.action = action; std::list<Breakpoint> qualifiedBreakpoints = getQualifiedInvokeBreakpoints(impl, invokeElem, invokeId, breakpointTemplate); session->checkBreakpoints(qualifiedBreakpoints); }
void Debugger::handleMicrostep(Interpreter& interpreter, Breakpoint::When when) { InterpreterImpl* impl = interpreter.getImpl().get(); std::shared_ptr<DebugSession> session = getSession(impl); if (!session) return; if (!session->_isRunning) return; std::list<Breakpoint> breakpoints; Breakpoint breakpoint; breakpoint.when = when; breakpoint.subject = Breakpoint::MICROSTEP; breakpoints.push_back(breakpoint); session->checkBreakpoints(breakpoints); }
void Debugger::handleEvent(Interpreter& interpreter, const Event& event, Breakpoint::When when) { InterpreterImpl* impl = interpreter.getImpl().get(); std::shared_ptr<DebugSession> session = getSession(impl); if (!session) return; if (!session->_isRunning) 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::handleExecutable(Interpreter& interpreter, const XERCESC_NS::DOMElement* execContentElem, Breakpoint::When when) { std::shared_ptr<DebugSession> session = getSession(interpreter.getImpl().get()); if (!session) return; if (!session->_isRunning) return; std::list<Breakpoint> breakpoints; Breakpoint breakpoint; breakpoint.when = when; breakpoint.element = execContentElem; breakpoint.executableName = X(execContentElem->getLocalName()).str(); breakpoint.subject = Breakpoint::EXECUTABLE; breakpoints.push_back(breakpoint); session->checkBreakpoints(breakpoints); }
int main(int argc, char** argv) { try { using namespace uscxml; using namespace Arabica::DOM; using namespace Arabica::XPath; const char* xml = "<scxml>" " <state id=\"atomic\" />" " <state id=\"compound\">" " <state id=\"compoundChild1\" />" " <state id=\"compoundChild2\" />" " </state>" " <parallel id=\"parallel\">" " </parallel>" "</scxml>"; Interpreter interpreter = Interpreter::fromXML(xml); assert(interpreter); interpreter.getImpl()->init(); Element<std::string> atomicState = interpreter.getImpl()->getState("atomic"); assert(InterpreterImpl::isAtomic(atomicState)); assert(!InterpreterImpl::isParallel(atomicState)); assert(!InterpreterImpl::isCompound(atomicState)); Element<std::string> compoundState = interpreter.getImpl()->getState("compound"); assert(!InterpreterImpl::isAtomic(compoundState)); assert(!InterpreterImpl::isParallel(compoundState)); assert(InterpreterImpl::isCompound(compoundState)); Element<std::string> parallelState = interpreter.getImpl()->getState("parallel"); assert(!InterpreterImpl::isAtomic(parallelState)); assert(InterpreterImpl::isParallel(parallelState)); assert(!InterpreterImpl::isCompound(parallelState)); // parallel states are not compound! NodeSet<std::string> initialState = interpreter.getImpl()->getInitialStates(); assert(initialState[0] == atomicState); NodeSet<std::string> childs = interpreter.getImpl()->getChildStates(compoundState); Node<std::string> compoundChild1 = interpreter.getImpl()->getState("compoundChild1"); Node<std::string> compoundChild2 = interpreter.getImpl()->getState("compoundChild2"); assert(childs.size() > 0); assert(InterpreterImpl::isMember(compoundChild1, childs)); assert(InterpreterImpl::isMember(compoundChild2, childs)); assert(!InterpreterImpl::isMember(compoundState, childs)); assert(InterpreterImpl::isDescendant(compoundChild1, compoundState)); { std::string idrefs("id1"); std::list<std::string> tokenizedIdrefs = InterpreterImpl::tokenizeIdRefs(idrefs); assert(tokenizedIdrefs.size() == 1); assert(tokenizedIdrefs.front().compare("id1") == 0); } { std::string idrefs(" id1"); std::list<std::string> tokenizedIdrefs = InterpreterImpl::tokenizeIdRefs(idrefs); assert(tokenizedIdrefs.size() == 1); assert(tokenizedIdrefs.front().compare("id1") == 0); } { std::string idrefs(" id1 "); std::list<std::string> tokenizedIdrefs = InterpreterImpl::tokenizeIdRefs(idrefs); assert(tokenizedIdrefs.size() == 1); assert(tokenizedIdrefs.front().compare("id1") == 0); } { std::string idrefs(" \tid1\n "); std::list<std::string> tokenizedIdrefs = InterpreterImpl::tokenizeIdRefs(idrefs); assert(tokenizedIdrefs.size() == 1); assert(tokenizedIdrefs.front().compare("id1") == 0); } { std::string idrefs("id1 id2 id3"); std::list<std::string> tokenizedIdrefs = InterpreterImpl::tokenizeIdRefs(idrefs); assert(tokenizedIdrefs.size() == 3); assert(tokenizedIdrefs.front().compare("id1") == 0); tokenizedIdrefs.pop_front(); assert(tokenizedIdrefs.front().compare("id2") == 0); tokenizedIdrefs.pop_front(); assert(tokenizedIdrefs.front().compare("id3") == 0); } { std::string idrefs("\t id1 \nid2\n\n id3\t"); std::list<std::string> tokenizedIdrefs = InterpreterImpl::tokenizeIdRefs(idrefs); assert(tokenizedIdrefs.size() == 3); assert(tokenizedIdrefs.front().compare("id1") == 0); tokenizedIdrefs.pop_front(); assert(tokenizedIdrefs.front().compare("id2") == 0); tokenizedIdrefs.pop_front(); assert(tokenizedIdrefs.front().compare("id3") == 0); } { std::string idrefs("id1 \nid2 \tid3"); std::list<std::string> tokenizedIdrefs = InterpreterImpl::tokenizeIdRefs(idrefs); assert(tokenizedIdrefs.size() == 3); assert(tokenizedIdrefs.front().compare("id1") == 0); tokenizedIdrefs.pop_front(); assert(tokenizedIdrefs.front().compare("id2") == 0); tokenizedIdrefs.pop_front(); assert(tokenizedIdrefs.front().compare("id3") == 0); } std::string transEvents; transEvents = "error"; assert(InterpreterImpl::nameMatch(transEvents, "error")); assert(!InterpreterImpl::nameMatch(transEvents, "foo")); transEvents = "error foo"; assert(InterpreterImpl::nameMatch(transEvents, "error")); assert(InterpreterImpl::nameMatch(transEvents, "error.send")); assert(InterpreterImpl::nameMatch(transEvents, "error.send.failed")); assert(InterpreterImpl::nameMatch(transEvents, "foo")); assert(InterpreterImpl::nameMatch(transEvents, "foo.bar")); assert(!InterpreterImpl::nameMatch(transEvents, "errors.my.custom")); assert(!InterpreterImpl::nameMatch(transEvents, "errorhandler.mistake")); // is the event name case sensitive? // assert(!InterpreterImpl::nameMatch(transEvents, "errOr.send")); assert(!InterpreterImpl::nameMatch(transEvents, "foobar")); } catch(std::exception e) { std::cout << e.what(); return false; } catch(uscxml::Event e) { std::cout << e; return false; } }