summaryrefslogtreecommitdiffstats
path: root/src/uscxml/debug/InterpreterIssue.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/uscxml/debug/InterpreterIssue.cpp')
-rw-r--r--src/uscxml/debug/InterpreterIssue.cpp601
1 files changed, 349 insertions, 252 deletions
diff --git a/src/uscxml/debug/InterpreterIssue.cpp b/src/uscxml/debug/InterpreterIssue.cpp
index 1bb14f6..ce61af6 100644
--- a/src/uscxml/debug/InterpreterIssue.cpp
+++ b/src/uscxml/debug/InterpreterIssue.cpp
@@ -20,67 +20,128 @@
#include <string>
#include "InterpreterIssue.h"
-#include "uscxml/dom/DOMUtils.h"
-#include "uscxml/debug/Complexity.h"
+#include "uscxml/util/DOM.h"
+#include "uscxml/util/String.h"
+#include "uscxml/util/Predicates.h"
+//#include "uscxml/debug/Complexity.h"
#include "uscxml/Interpreter.h"
-#include "uscxml/Factory.h"
+#include "uscxml/plugins/Factory.h"
-#include <XPath/XPath.hpp>
-#include <DOM/Document.hpp>
+#include <xercesc/dom/DOMDocument.hpp>
namespace uscxml {
-using namespace Arabica::XPath;
-using namespace Arabica::DOM;
+using namespace xercesc;
-InterpreterIssue::InterpreterIssue(const std::string& msg, Arabica::DOM::Node<std::string> node, IssueSeverity severity, const std::string& specRef) : message(msg), node(node), severity(severity), specRef(specRef) {
+InterpreterIssue::InterpreterIssue(const std::string& msg, DOMNode* node, IssueSeverity severity, const std::string& specRef) : message(msg), node(node), severity(severity), specRef(specRef) {
if (node)
xPath = DOMUtils::xPathForNode(node);
}
// find all elements in the SCXML namespace in one traversal
-void assembleNodeSets(const std::string nsPrefix, const Node<std::string>& node, std::map<std::string, NodeSet<std::string> >& sets) {
- NodeList<std::string> childs = node.getChildNodes();
- for (unsigned int i = 0; i < childs.getLength(); i++) {
- if (childs.item(i).getNodeType() != Node_base::ELEMENT_NODE)
+void assembleNodeSets(const std::string nsPrefix, DOMNode* node, std::map<std::string, std::list<DOMElement*> >& sets) {
+ DOMNodeList* childs = node->getChildNodes();
+ for (unsigned int i = 0; i < childs->getLength(); i++) {
+ if (childs->item(i)->getNodeType() != DOMNode::ELEMENT_NODE)
continue;
// std::cout << TAGNAME(childs.item(i)) << std::endl;
- if (TAGNAME_CAST(childs.item(i)).find(nsPrefix) == 0) {
+ if (TAGNAME_CAST(childs->item(i)).find(nsPrefix) == 0) {
// correct namespace, insert via localname
- sets[LOCALNAME_CAST(childs.item(i))].push_back(childs.item(i));
+ sets[LOCALNAME_CAST(childs->item(i))].push_back(static_cast<DOMElement*>(childs->item(i)));
}
- assembleNodeSets(nsPrefix, childs.item(i), sets);
+ assembleNodeSets(nsPrefix, childs->item(i), sets);
}
}
+std::list<std::set<const DOMElement* > > getAllConfigurations(const DOMElement* root) {
+ std::list<std::set<const DOMElement* > > allConfigurations;
+ std::string nsPrefix = X(root->getPrefix());
+ std::string localName = X(root->getLocalName());
+ bool isAtomic = true;
+
+ std::cout << *root;
+
+ DOMNodeList* children = root->getChildNodes();
+ for (size_t i = 0; i < children->getLength(); i++) {
+ if (children->item(i)->getNodeType() != DOMNode::ELEMENT_NODE)
+ continue;
+ DOMElement* childElem = static_cast<DOMElement*>(children->item(i));
+ std::cout << *childElem;
+
+ if (XMLString::compareIString(childElem->getTagName(), X(nsPrefix + "state")) == 0 ||
+ XMLString::compareIString(childElem->getTagName(), X(nsPrefix + "parallel")) == 0 ||
+ XMLString::compareIString(childElem->getTagName(), X(nsPrefix + "final")) == 0) {
+ // nested child state
+ std::list<std::set<const DOMElement*> > nestedConfigurations = getAllConfigurations(childElem);
+ isAtomic = false;
+ if (localName == "parallel" && allConfigurations.size() > 0) {
+ // for every nested configuration, every new nested is valid
+ std::list<std::set<const DOMElement*> > combinedConfigurations;
+ for (auto existIter = allConfigurations.begin(); existIter != allConfigurations.end(); existIter++) {
+ std::set<const DOMElement*> existingConfig = *existIter;
+
+ for (auto newIter = nestedConfigurations.begin(); newIter != nestedConfigurations.end(); newIter++) {
+
+ std::set<const DOMElement*> newConfig = *newIter;
+ std::set<const DOMElement*> combinedSet;
+ combinedSet.insert(existingConfig.begin(), existingConfig.end());
+ combinedSet.insert(newConfig.begin(), newConfig.end());
+
+ combinedConfigurations.push_back(combinedSet);
+ }
+ }
+ allConfigurations = combinedConfigurations;
+ } else {
+ // just add nested configurations and this
+ for (auto newIter = nestedConfigurations.begin(); newIter != nestedConfigurations.end(); newIter++) {
+ std::set<const DOMElement*> newConfig = *newIter;
+ if (localName != "scxml")
+ newConfig.insert(root);
+ allConfigurations.push_back(newConfig);
+ }
+ }
+ }
+ }
+
+ if (isAtomic) {
+ std::set<const DOMElement*> soleConfig;
+ soleConfig.insert(root);
+ allConfigurations.push_back(soleConfig);
+ }
+ return allConfigurations;
+
+}
/**
* Can the given states ever appear in an active configuration?
*/
-bool hasLegalCompletion(const NodeSet<std::string>& states) {
+bool hasLegalCompletion(const std::list<DOMElement*>& states) {
if (states.size() < 2)
return true;
// iterate every pair
- for (unsigned int outer = 0; outer < states.size() - 1; outer++) {
- Element<std::string> s1(states[outer]);
- for (unsigned int inner = outer + 1; inner < states.size(); inner++) {
- Element<std::string> s2(states[inner]);
- Node<std::string> parent;
+ for (auto outer = states.begin(); outer != states.end(); outer++) {
+ DOMElement* s1 = *outer;
+ for (auto inner = outer; inner != states.end(); inner++) {
+ if (inner == outer)
+ continue;
+
+ DOMElement* s2 = *inner;
+ DOMNode* parent;
// ok to be directly ancestorally related
- if (InterpreterImpl::isDescendant(s1, s2) || InterpreterImpl::isDescendant(s2, s1))
+ if (DOMUtils::isDescendant(s1, s2) || DOMUtils::isDescendant(s2, s1))
goto NEXT_PAIR;
// find least common ancestor
- parent = s1.getParentNode();
- while(parent && parent.getNodeType() == Node_base::ELEMENT_NODE) {
- if (InterpreterImpl::isDescendant(s2, parent)) {
- if (InterpreterImpl::isParallel(Element<std::string>(parent)))
+ parent = s1->getParentNode();
+ while(parent && parent->getNodeType() == DOMNode::ELEMENT_NODE) {
+ if (DOMUtils::isDescendant(s2, parent)) {
+ if (isParallel(static_cast<DOMElement*>(parent)))
goto NEXT_PAIR;
}
- parent = parent.getParentNode();
+ parent = parent->getParentNode();
}
return false;
@@ -100,91 +161,90 @@ std::list<InterpreterIssue> InterpreterIssue::forInterpreter(InterpreterImpl* in
std::list<InterpreterIssue> issues;
if (!interpreter->_scxml) {
- InterpreterIssue issue("No SCXML element to be found", Node<std::string>(), InterpreterIssue::USCXML_ISSUE_FATAL);
+ InterpreterIssue issue("No SCXML element to be found", NULL, InterpreterIssue::USCXML_ISSUE_FATAL);
issues.push_back(issue);
return issues;
}
- std::map<std::string, Arabica::DOM::Element<std::string> > seenStates;
+ std::map<std::string, DOMElement* > seenStates;
// get some aliases
- Element<std::string>& _scxml = interpreter->_scxml;
- NameSpaceInfo& _nsInfo = interpreter->_nsInfo;
+ DOMElement* _scxml = interpreter->_scxml;
Factory* _factory = interpreter->_factory;
DataModel& _dataModel = interpreter->_dataModel;
+ std::string xmlNSPrefix = interpreter->_xmlPrefix;
+ std::map<std::string, std::list<DOMElement*> > nodeSets;
+ assembleNodeSets(xmlNSPrefix, _scxml, nodeSets);
- std::map<std::string, NodeSet<std::string> > nodeSets;
- assembleNodeSets(_nsInfo.xmlNSPrefix, _scxml, nodeSets);
-
- NodeSet<std::string> scxmls = nodeSets["scxml"];
+ std::list<DOMElement*> scxmls = nodeSets["scxml"];
scxmls.push_back(_scxml);
- NodeSet<std::string> reachable = interpreter->getReachableStates();
-
- NodeSet<std::string>& states = nodeSets["state"];
- NodeSet<std::string>& parallels = nodeSets["parallel"];
- NodeSet<std::string>& transitions = nodeSets["transition"];
- NodeSet<std::string>& initials = nodeSets["initial"];
- NodeSet<std::string>& finals = nodeSets["final"];
- NodeSet<std::string>& onEntries = nodeSets["onentry"];
- NodeSet<std::string>& onExits = nodeSets["onexit"];
- NodeSet<std::string>& histories = nodeSets["history"];
-
- NodeSet<std::string>& raises = nodeSets["raise"];
- NodeSet<std::string>& ifs = nodeSets["if"];
- NodeSet<std::string>& elseIfs = nodeSets["elseif"];
- NodeSet<std::string>& elses = nodeSets["else"];
- NodeSet<std::string>& foreachs = nodeSets["foreach"];
- NodeSet<std::string>& logs = nodeSets["log"];
-
- NodeSet<std::string>& dataModels = nodeSets["datamodel"];
- NodeSet<std::string>& datas = nodeSets["data"];
- NodeSet<std::string>& assigns = nodeSets["assign"];
- NodeSet<std::string>& doneDatas = nodeSets["donedata"];
- NodeSet<std::string>& contents = nodeSets["content"];
- NodeSet<std::string>& params = nodeSets["param"];
- NodeSet<std::string>& scripts = nodeSets["script"];
-
- NodeSet<std::string>& sends = nodeSets["send"];
- NodeSet<std::string>& cancels = nodeSets["cancel"];
- NodeSet<std::string>& invokes = nodeSets["invoke"];
- NodeSet<std::string>& finalizes = nodeSets["finalize"];
-
- NodeSet<std::string> allStates;
- allStates.push_back(states);
- allStates.push_back(parallels);
- allStates.push_back(histories);
- allStates.push_back(finals);
-
- NodeSet<std::string> allExecContents;
- allExecContents.push_back(raises);
- allExecContents.push_back(ifs);
- allExecContents.push_back(elseIfs);
- allExecContents.push_back(elses);
- allExecContents.push_back(foreachs);
- allExecContents.push_back(logs);
- allExecContents.push_back(sends);
- allExecContents.push_back(assigns);
- allExecContents.push_back(scripts);
- allExecContents.push_back(cancels);
-
- NodeSet<std::string> allElements;
- allElements.push_back(scxmls);
- allElements.push_back(allStates);
- allElements.push_back(allExecContents);
- allElements.push_back(transitions);
- allElements.push_back(initials);
- allElements.push_back(onEntries);
- allElements.push_back(onExits);
- allElements.push_back(dataModels);
- allElements.push_back(datas);
- allElements.push_back(doneDatas);
- allElements.push_back(contents);
- allElements.push_back(params);
- allElements.push_back(invokes);
- allElements.push_back(finalizes);
+ std::list<xercesc::DOMElement*> reachable = getReachableStates(_scxml);
+
+ std::list<DOMElement*>& states = nodeSets["state"];
+ std::list<DOMElement*>& parallels = nodeSets["parallel"];
+ std::list<DOMElement*>& transitions = nodeSets["transition"];
+ std::list<DOMElement*>& initials = nodeSets["initial"];
+ std::list<DOMElement*>& finals = nodeSets["final"];
+ std::list<DOMElement*>& onEntries = nodeSets["onentry"];
+ std::list<DOMElement*>& onExits = nodeSets["onexit"];
+ std::list<DOMElement*>& histories = nodeSets["history"];
+
+ std::list<DOMElement*>& raises = nodeSets["raise"];
+ std::list<DOMElement*>& ifs = nodeSets["if"];
+ std::list<DOMElement*>& elseIfs = nodeSets["elseif"];
+ std::list<DOMElement*>& elses = nodeSets["else"];
+ std::list<DOMElement*>& foreachs = nodeSets["foreach"];
+ std::list<DOMElement*>& logs = nodeSets["log"];
+
+ std::list<DOMElement*>& dataModels = nodeSets["datamodel"];
+ std::list<DOMElement*>& datas = nodeSets["data"];
+ std::list<DOMElement*>& assigns = nodeSets["assign"];
+ std::list<DOMElement*>& doneDatas = nodeSets["donedata"];
+ std::list<DOMElement*>& contents = nodeSets["content"];
+ std::list<DOMElement*>& params = nodeSets["param"];
+ std::list<DOMElement*>& scripts = nodeSets["script"];
+
+ std::list<DOMElement*>& sends = nodeSets["send"];
+ std::list<DOMElement*>& cancels = nodeSets["cancel"];
+ std::list<DOMElement*>& invokes = nodeSets["invoke"];
+ std::list<DOMElement*>& finalizes = nodeSets["finalize"];
+
+ std::list<DOMElement*> allStates;
+ allStates.insert(allStates.end(), states.begin(), states.end());
+ allStates.insert(allStates.end(), parallels.begin(), parallels.end());
+ allStates.insert(allStates.end(), histories.begin(), histories.end());
+ allStates.insert(allStates.end(), finals.begin(), finals.end());
+
+ std::list<DOMElement*> allExecContents;
+ allExecContents.insert(allExecContents.end(), raises.begin(), raises.end());
+ allExecContents.insert(allExecContents.end(), ifs.begin(), ifs.end());
+ allExecContents.insert(allExecContents.end(), elseIfs.begin(), elseIfs.end());
+ allExecContents.insert(allExecContents.end(), elses.begin(), elses.end());
+ allExecContents.insert(allExecContents.end(), foreachs.begin(), foreachs.end());
+ allExecContents.insert(allExecContents.end(), logs.begin(), logs.end());
+ allExecContents.insert(allExecContents.end(), sends.begin(), sends.end());
+ allExecContents.insert(allExecContents.end(), assigns.begin(), assigns.end());
+ allExecContents.insert(allExecContents.end(), scripts.begin(), scripts.end());
+ allExecContents.insert(allExecContents.end(), cancels.begin(), cancels.end());
+
+ std::list<DOMElement*> allElements;
+ allElements.insert(allElements.end(), scxmls.begin(), scxmls.end());
+ allElements.insert(allElements.end(), allStates.begin(), allStates.end());
+ allElements.insert(allElements.end(), allExecContents.begin(), allExecContents.end());
+ allElements.insert(allElements.end(), transitions.begin(), transitions.end());
+ allElements.insert(allElements.end(), initials.begin(), initials.end());
+ allElements.insert(allElements.end(), onEntries.begin(), onEntries.end());
+ allElements.insert(allElements.end(), onExits.begin(), onExits.end());
+ allElements.insert(allElements.end(), dataModels.begin(), dataModels.end());
+ allElements.insert(allElements.end(), datas.begin(), datas.end());
+ allElements.insert(allElements.end(), doneDatas.begin(), doneDatas.end());
+ allElements.insert(allElements.end(), contents.begin(), contents.end());
+ allElements.insert(allElements.end(), params.begin(), params.end());
+ allElements.insert(allElements.end(), invokes.begin(), invokes.end());
+ allElements.insert(allElements.end(), finalizes.begin(), finalizes.end());
std::set<std::string> execContentSet;
@@ -278,10 +338,10 @@ std::list<InterpreterIssue> InterpreterIssue::forInterpreter(InterpreterImpl* in
}
- for (size_t i = 0; i < allStates.size(); i++) {
- Element<std::string> state = Element<std::string>(allStates[i]);
+ for (auto stateIter = allStates.begin(); stateIter != allStates.end(); stateIter++) {
+ DOMElement* state = static_cast<DOMElement*>(*stateIter);
- if (InterpreterImpl::isMember(state, finals) && !HAS_ATTR(state, "id")) // id is not required for finals
+ if (DOMUtils::isMember(state, finals) && !HAS_ATTR(state, "id")) // id is not required for finals
continue;
// check for existance of id attribute - this not actually required!
@@ -299,13 +359,13 @@ std::list<InterpreterIssue> InterpreterIssue::forInterpreter(InterpreterImpl* in
// check for valid transition with history states
if (LOCALNAME(state) == "history") {
- NodeSet<std::string> transitions = DOMUtils::filterChildElements(_nsInfo.xmlNSPrefix + "transition", state, false);
+ std::list<DOMElement*> transitions = DOMUtils::filterChildElements(XML_PREFIX(state).str() + "transition", state, false);
if (transitions.size() > 1) {
issues.push_back(InterpreterIssue("History pseudo-state with id '" + stateId + "' has multiple transitions", state, InterpreterIssue::USCXML_ISSUE_FATAL));
} else if (transitions.size() == 0) {
issues.push_back(InterpreterIssue("History pseudo-state with id '" + stateId + "' has no default transition", state, InterpreterIssue::USCXML_ISSUE_FATAL));
} else {
- Element<std::string> transition = Element<std::string>(transitions[0]);
+ DOMElement* transition = static_cast<DOMElement*>(transitions.front());
if (HAS_ATTR(transition, "cond")) {
issues.push_back(InterpreterIssue("Transition in history pseudo-state '" + stateId + "' must not have a condition", transition, InterpreterIssue::USCXML_ISSUE_FATAL));
}
@@ -315,16 +375,16 @@ std::list<InterpreterIssue> InterpreterIssue::forInterpreter(InterpreterImpl* in
if (!HAS_ATTR(transition, "target")) {
issues.push_back(InterpreterIssue("Transition in history pseudo-state '" + stateId + "' has no target", transition, InterpreterIssue::USCXML_ISSUE_FATAL));
} else {
- NodeSet<std::string> targetStates = interpreter->getTargetStates(transition);
- for (size_t j = 0; j < targetStates.size(); j++) {
- Element<std::string> target = Element<std::string>(targetStates[j]);
+ std::list<DOMElement*> targetStates = getTargetStates(transition, _scxml);
+ for (auto tIter = targetStates.begin(); tIter != targetStates.end(); tIter++) {
+ DOMElement* target = *tIter;
if (HAS_ATTR(state, "type") && ATTR(state, "type") == "deep") {
- if (!InterpreterImpl::isDescendant(target, state.getParentNode())) {
- issues.push_back(InterpreterIssue("Transition in deep history pseudo-state '" + stateId + "' has invalid target state '" + ATTR(target, "id") + "'", transition, InterpreterIssue::USCXML_ISSUE_FATAL));
+ if (!DOMUtils::isDescendant(target, state->getParentNode())) {
+ issues.push_back(InterpreterIssue("Transition in deep history pseudo-state '" + stateId + "' has illegal target state '" + ATTR(target, "id") + "'", transition, InterpreterIssue::USCXML_ISSUE_FATAL));
}
} else {
- if (target.getParentNode() != state.getParentNode()) {
- issues.push_back(InterpreterIssue("Transition in shallow history pseudo-state '" + stateId + "' has invalid target state '" + ATTR(target, "id") + "'", transition, InterpreterIssue::USCXML_ISSUE_FATAL));
+ if (target->getParentNode() != state->getParentNode()) {
+ issues.push_back(InterpreterIssue("Transition in shallow history pseudo-state '" + stateId + "' has illegal target state '" + ATTR(target, "id") + "'", transition, InterpreterIssue::USCXML_ISSUE_FATAL));
}
}
}
@@ -333,7 +393,7 @@ std::list<InterpreterIssue> InterpreterIssue::forInterpreter(InterpreterImpl* in
}
// check whether state is reachable
- if (!InterpreterImpl::isMember(state, reachable) && !InterpreterImpl::isInEmbeddedDocument(state)) {
+ if (!DOMUtils::isMember(state, reachable) && !isInEmbeddedDocument(state)) {
issues.push_back(InterpreterIssue("State with id '" + stateId + "' is unreachable", state, InterpreterIssue::USCXML_ISSUE_FATAL));
}
@@ -345,8 +405,8 @@ std::list<InterpreterIssue> InterpreterIssue::forInterpreter(InterpreterImpl* in
seenStates[ATTR(state, "id")] = state;
}
- for (size_t i = 0; i < transitions.size(); i++) {
- Element<std::string> transition = Element<std::string>(transitions[i]);
+ for (auto tIter = transitions.begin(); tIter != transitions.end(); tIter++) {
+ DOMElement* transition = *tIter;
// check for valid target
if (HAS_ATTR(transition, "target")) {
@@ -365,16 +425,14 @@ std::list<InterpreterIssue> InterpreterIssue::forInterpreter(InterpreterImpl* in
}
// check for redundancy of transition
- for (size_t i = 0; i < allStates.size(); i++) {
- Element<std::string> state = Element<std::string>(allStates[i]);
- NodeSet<std::string> transitions = DOMUtils::filterChildElements(_nsInfo.xmlNSPrefix + "transition", state, false);
-
- transitions.to_document_order();
+ for (auto stateIter = allStates.begin(); stateIter != allStates.end(); stateIter++) {
+ DOMElement* state = *stateIter;
+ std::list<DOMElement*> transitions = DOMUtils::filterChildElements(XML_PREFIX(state).str() + "transition", state, false);
- for (size_t j = 1; j < transitions.size(); j++) {
- Element<std::string> transition = Element<std::string>(transitions[j]);
- for (size_t k = 0; k < j; k++) {
- Element<std::string> earlierTransition = Element<std::string>(transitions[k]);
+ for (auto tIter = transitions.begin(); tIter != transitions.end(); tIter++) {
+ DOMElement* transition = *tIter;
+ for (auto t2Iter = transitions.begin(); t2Iter != tIter; t2Iter++) {
+ DOMElement* earlierTransition = *t2Iter;
// will the earlier transition always be enabled when the later is?
if (!HAS_ATTR(earlierTransition, "cond")) {
@@ -410,16 +468,18 @@ NEXT_TRANSITION:
// check for useless history elements
{
- for (size_t i = 0; i < histories.size(); i++) {
- Element<std::string> history = Element<std::string>(histories[i]);
- if (!history.getParentNode() || history.getParentNode().getNodeType() != Node_base::ELEMENT_NODE)
+ for (auto histIter = histories.begin(); histIter != histories.end(); histIter++) {
+ DOMElement* history = *histIter;
+
+ if (!history->getParentNode() || history->getParentNode()->getNodeType() != DOMNode::ELEMENT_NODE)
continue; // syntax check will have catched this
- Element<std::string> parent(history.getParentNode());
- if (InterpreterImpl::isAtomic(parent)) {
+
+ DOMElement* parent = static_cast<DOMElement*>(history->getParentNode());
+ if (isAtomic(parent)) {
issues.push_back(InterpreterIssue("Useless history '" + ATTR(history, "id") + "' in atomic state", history, InterpreterIssue::USCXML_ISSUE_INFO));
continue;
}
- std::list<std::set<Arabica::DOM::Element<std::string> > > configs = Complexity::getAllConfigurations(parent);
+ std::list<std::set<const DOMElement* > > configs = getAllConfigurations(parent);
if (configs.size() <= 1) {
issues.push_back(InterpreterIssue("Useless history '" + ATTR(history, "id") + "' in state with single legal configuration", history, InterpreterIssue::USCXML_ISSUE_INFO));
continue;
@@ -429,19 +489,24 @@ NEXT_TRANSITION:
// check for valid initial attribute
{
- NodeSet<std::string> withInitialAttr;
- withInitialAttr.push_back(allStates);
+ std::list<DOMElement*> withInitialAttr;
+ withInitialAttr.insert(withInitialAttr.end(), allStates.begin(), allStates.end());
withInitialAttr.push_back(_scxml);
- for (size_t i = 0; i < withInitialAttr.size(); i++) {
- Element<std::string> state = Element<std::string>(withInitialAttr[i]);
+ for (auto stateIter = withInitialAttr.begin(); stateIter != withInitialAttr.end(); stateIter++) {
+ DOMElement* state = *stateIter;
if (HAS_ATTR(state, "initial")) {
- NodeSet<std::string> childs;
- childs.push_back(DOMUtils::filterChildElements(_nsInfo.xmlNSPrefix + "state", state, true));
- childs.push_back(DOMUtils::filterChildElements(_nsInfo.xmlNSPrefix + "parallel", state, true));
- childs.push_back(DOMUtils::filterChildElements(_nsInfo.xmlNSPrefix + "final", state, true));
- childs.push_back(DOMUtils::filterChildElements(_nsInfo.xmlNSPrefix + "history", state, true));
+ std::list<DOMElement*> childs;
+ std::list<DOMElement*> tmp;
+ tmp = DOMUtils::filterChildElements(XML_PREFIX(state).str() + "state", state, true);
+ childs.insert(childs.end(), tmp.begin(), tmp.end());
+ tmp = DOMUtils::filterChildElements(XML_PREFIX(state).str() + "parallel", state, true);
+ childs.insert(childs.end(), tmp.begin(), tmp.end());
+ tmp = DOMUtils::filterChildElements(XML_PREFIX(state).str() + "final", state, true);
+ childs.insert(childs.end(), tmp.begin(), tmp.end());
+ tmp = DOMUtils::filterChildElements(XML_PREFIX(state).str() + "history", state, true);
+ childs.insert(childs.end(), tmp.begin(), tmp.end());
std::list<std::string> intials = tokenize(ATTR(state, "initial"));
for (std::list<std::string>::iterator initIter = intials.begin(); initIter != intials.end(); initIter++) {
@@ -450,7 +515,7 @@ NEXT_TRANSITION:
continue;
}
// value of the 'initial' attribute [..] must be descendants of the containing <state> or <parallel> element
- if (!InterpreterImpl::isMember(seenStates[*initIter], childs)) {
+ if (!DOMUtils::isMember(seenStates[*initIter], childs)) {
issues.push_back(InterpreterIssue("Initial attribute references non-child state '" + *initIter + "'", state, InterpreterIssue::USCXML_ISSUE_FATAL));
}
}
@@ -460,37 +525,37 @@ NEXT_TRANSITION:
// check for legal configuration of target sets
{
- std::map<Element<std::string>, std::string > targetIdSets;
- for (size_t i = 0; i < transitions.size(); i++) {
- Element<std::string> transition = Element<std::string>(transitions[i]);
+ std::map<DOMElement*, std::string > targetIdSets;
+ for (auto iter = transitions.begin(); iter != transitions.end(); iter++) {
+ DOMElement* transition = *iter;
if (HAS_ATTR(transition, "target")) {
targetIdSets[transition] = ATTR(transition, "target");
}
}
- for (size_t i = 0; i < initials.size(); i++) {
- Element<std::string> initial = Element<std::string>(initials[i]);
+ for (auto iter = initials.begin(); iter != initials.end(); iter++) {
+ DOMElement* initial = *iter;
if (HAS_ATTR(initial, "target")) {
targetIdSets[initial] = ATTR(initial, "target");
}
}
- for (size_t i = 0; i < allStates.size(); i++) {
- Element<std::string> state = Element<std::string>(allStates[i]);
+ for (auto iter = allStates.begin(); iter != allStates.end(); iter++) {
+ DOMElement* state = *iter;
if (HAS_ATTR(state, "initial")) {
targetIdSets[state] = ATTR(state, "initial");
}
}
- for (std::map<Element<std::string>, std::string >::iterator setIter = targetIdSets.begin();
+ for (auto setIter = targetIdSets.begin();
setIter != targetIdSets.end();
setIter++) {
- NodeSet<std::string> targets;
+ std::list<DOMElement*> targets;
std::list<std::string> targetIds = tokenize(setIter->second);
- for (std::list<std::string>::iterator tgtIter = targetIds.begin(); tgtIter != targetIds.end(); tgtIter++) {
+ for (auto tgtIter = targetIds.begin(); tgtIter != targetIds.end(); tgtIter++) {
if (seenStates.find(*tgtIter) == seenStates.end())
goto NEXT_SET;
targets.push_back(seenStates[*tgtIter]);
@@ -505,21 +570,21 @@ NEXT_SET:
// check for valid initial transition
{
- NodeSet<std::string> initTrans;
-// initTrans.push_back(DOMUtils::filterChildElements(_nsInfo.xmlNSPrefix + "transition", histories, true));
+ std::list<DOMElement*> initTrans;
+
+ for (auto iter = initials.begin(); iter != initials.end(); iter++) {
+ DOMElement* initial = *iter;
- for (size_t i = 0; i < initials.size(); i++) {
- Element<std::string> initial = Element<std::string>(initials[i]);
- NodeSet<std::string> initTransitions = DOMUtils::filterChildElements(_nsInfo.xmlNSPrefix + "transition", initial, true);
+ std::list<DOMElement*> initTransitions = DOMUtils::filterChildElements(XML_PREFIX(initial).str() + "transition", initial, true);
if (initTransitions.size() != 1) {
issues.push_back(InterpreterIssue("Initial element must define exactly one transition", initial, InterpreterIssue::USCXML_ISSUE_FATAL));
}
- initTrans.push_back(initTransitions);
+ initTrans.insert(initTrans.end(), initTransitions.begin(), initTransitions.end());
}
- for (size_t i = 0; i < initTrans.size(); i++) {
- Element<std::string> transition = Element<std::string>(initTrans[i]);
+ for (auto iter = initTrans.begin(); iter != initTrans.end(); iter++) {
+ DOMElement* transition = *iter;
/* In a conformant SCXML document, this transition must not contain 'cond' or 'event' attributes, and must specify a non-null 'target'
* whose value is a valid state specification consisting solely of descendants of the containing state
@@ -532,22 +597,29 @@ NEXT_SET:
issues.push_back(InterpreterIssue("Initial transition cannot be eventful", transition, InterpreterIssue::USCXML_ISSUE_FATAL));
}
- if (!transition.getParentNode() || !transition.getParentNode().getParentNode() || transition.getParentNode().getParentNode().getNodeType() != Node_base::ELEMENT_NODE)
+ if (!transition->getParentNode() ||
+ !transition->getParentNode()->getParentNode() ||
+ transition->getParentNode()->getParentNode()->getNodeType() != DOMNode::ELEMENT_NODE)
continue; // syntax will catch this one
- Element<std::string> state(transition.getParentNode().getParentNode());
- if (!InterpreterImpl::isState(state))
+ DOMElement* state = static_cast<DOMElement*>(transition->getParentNode()->getParentNode());
+ if (!isState(state))
continue; // syntax will catch this one
- NodeSet<std::string> childs;
- childs.push_back(DOMUtils::filterChildElements(_nsInfo.xmlNSPrefix + "state", state, true));
- childs.push_back(DOMUtils::filterChildElements(_nsInfo.xmlNSPrefix + "parallel", state, true));
- childs.push_back(DOMUtils::filterChildElements(_nsInfo.xmlNSPrefix + "final", state, true));
- childs.push_back(DOMUtils::filterChildElements(_nsInfo.xmlNSPrefix + "history", state, true));
+ std::list<DOMElement*> childs;
+ std::list<DOMElement*> tmp;
+ tmp = DOMUtils::filterChildElements(XML_PREFIX(state).str() + "state", state, true);
+ childs.insert(childs.end(), tmp.begin(), tmp.end());
+ tmp = DOMUtils::filterChildElements(XML_PREFIX(state).str() + "parallel", state, true);
+ childs.insert(childs.end(), tmp.begin(), tmp.end());
+ tmp = DOMUtils::filterChildElements(XML_PREFIX(state).str() + "final", state, true);
+ childs.insert(childs.end(), tmp.begin(), tmp.end());
+ tmp = DOMUtils::filterChildElements(XML_PREFIX(state).str() + "history", state, true);
+ childs.insert(childs.end(), tmp.begin(), tmp.end());
std::list<std::string> intials = tokenize(ATTR(transition, "target"));
for (std::list<std::string>::iterator initIter = intials.begin(); initIter != intials.end(); initIter++) {
// the 'target' of a <transition> inside an <initial> or <history> element: all the states must be descendants of the containing <state> or <parallel> element
- if (!InterpreterImpl::isMember(seenStates[*initIter], childs)) {
+ if (!DOMUtils::isMember(seenStates[*initIter], childs)) {
issues.push_back(InterpreterIssue("Target of initial transition references non-child state '" + *initIter + "'", transition, InterpreterIssue::USCXML_ISSUE_FATAL));
}
}
@@ -557,8 +629,8 @@ NEXT_SET:
// check that all invokers exists
{
- for (size_t i = 0; i < invokes.size(); i++) {
- Element<std::string> invoke = Element<std::string>(invokes[i]);
+ for (auto iter = invokes.begin(); iter != invokes.end(); iter++) {
+ DOMElement* invoke = *iter;
if (HAS_ATTR(invoke, "type") && !_factory->hasInvoker(ATTR(invoke, "type"))) {
// unknown at factory - adhoc extension?
if (HAS_ATTR(invoke, "id") && interpreter->_invokers.find(ATTR(invoke, "id")) != interpreter->_invokers.end())
@@ -580,10 +652,10 @@ NEXT_SET:
// check that all io processors exists
{
- for (size_t i = 0; i < sends.size(); i++) {
- Element<std::string> send = Element<std::string>(sends[i]);
+ for (auto iter = sends.begin(); iter != sends.end(); iter++) {
+ DOMElement* send = *iter;
if (HAS_ATTR(send, "type") && !_factory->hasIOProcessor(ATTR(send, "type"))) {
- if (interpreter->_ioProcessors.find(ATTR(send, "type")) != interpreter->_ioProcessors.end())
+ if (interpreter->_ioProcs.find(ATTR(send, "type")) != interpreter->_ioProcs.end())
continue; // not an issue, available ad-hoc
issues.push_back(InterpreterIssue("Send to unknown IO Processor '" + ATTR(send, "type") + "'", send, InterpreterIssue::USCXML_ISSUE_FATAL));
@@ -594,23 +666,24 @@ NEXT_SET:
// check that all custom executable content is known
{
- NodeSet<std::string> allExecContentContainers;
- allExecContentContainers.push_back(onEntries);
- allExecContentContainers.push_back(onExits);
- allExecContentContainers.push_back(transitions);
- allExecContentContainers.push_back(finalizes);
-
- for (size_t i = 0; i < allExecContentContainers.size(); i++) {
- Element<std::string> block = Element<std::string>(allExecContentContainers[i]);
- NodeSet<std::string> execContents = DOMUtils::filterChildType(Node_base::ELEMENT_NODE, block);
- for (size_t j = 0; j < execContents.size(); j++) {
- Element<std::string> execContent = Element<std::string>(execContents[j]);
+ std::list<DOMElement*> allExecContentContainers;
+ allExecContentContainers.insert(allExecContentContainers.end(), onEntries.begin(), onEntries.end());
+ allExecContentContainers.insert(allExecContentContainers.end(), onExits.begin(), onExits.end());
+ allExecContentContainers.insert(allExecContentContainers.end(), transitions.begin(), transitions.end());
+ allExecContentContainers.insert(allExecContentContainers.end(), finalizes.begin(), finalizes.end());
+
+ for (auto bIter = allExecContentContainers.begin(); bIter != allExecContentContainers.end(); bIter++) {
+ DOMElement* block = *bIter;
+ std::list<DOMNode*> execContents = DOMUtils::filterChildType(DOMNode::ELEMENT_NODE, block);
+ for (auto ecIter = execContents.begin(); ecIter != execContents.end(); ecIter++) {
+ DOMElement* execContent = static_cast<DOMElement*>(*ecIter);
// SCXML specific executable content, always available
- if (InterpreterImpl::isMember(execContent, allExecContents)) {
+ if (DOMUtils::isMember(execContent, allExecContents)) {
continue;
}
- if (!_factory->hasExecutableContent(execContent.getLocalName(), execContent.getNamespaceURI())) {
- issues.push_back(InterpreterIssue("Executable content element '" + execContent.getLocalName() + "' in namespace '" + execContent.getNamespaceURI() + "' unknown", execContent, InterpreterIssue::USCXML_ISSUE_FATAL));
+
+ if (!_factory->hasExecutableContent(X(execContent->getLocalName()), X(execContent->getNamespaceURI()))) {
+ issues.push_back(InterpreterIssue("Executable content element '" + (std::string)X(execContent->getLocalName()) + "' in namespace '" + (std::string)X(execContent->getNamespaceURI()) + "' unknown", execContent, InterpreterIssue::USCXML_ISSUE_FATAL));
continue;
}
}
@@ -619,8 +692,8 @@ NEXT_SET:
// check that all SCXML elements have valid parents and required attributes
{
- for (size_t i = 0; i < allElements.size(); i++) {
- Element<std::string> element = Element<std::string>(allElements[i]);
+ for (auto iter = allElements.begin(); iter != allElements.end(); iter++) {
+ DOMElement* element = *iter;
std::string localName = LOCALNAME(element);
if (reqAttr.find(localName) != reqAttr.end()) {
@@ -638,12 +711,12 @@ NEXT_SET:
if (localName == "scxml") // can be anywhere: <assign>, <content>, <other:embed>
continue;
- if (!element.getParentNode() || element.getParentNode().getNodeType() != Node_base::ELEMENT_NODE) {
+ if (!element->getParentNode() || element->getParentNode()->getNodeType() != DOMNode::ELEMENT_NODE) {
issues.push_back(InterpreterIssue("Parent of " + localName + " is no element", element, InterpreterIssue::USCXML_ISSUE_WARNING));
continue;
}
- Element<std::string> parent = Element<std::string>(element.getParentNode());
+ DOMElement* parent = static_cast<DOMElement*>(element->getParentNode());
std::string parentName = LOCALNAME(parent);
if (validParents[localName].find(parentName) == validParents[localName].end()) {
@@ -655,55 +728,55 @@ NEXT_SET:
// check attribute constraints
{
- for (size_t i = 0; i < initials.size(); i++) {
- Element<std::string> initial = Element<std::string>(initials[i]);
- if (initial.getParentNode() && initial.getParentNode().getNodeType() == Node_base::ELEMENT_NODE) {
- Element<std::string> state(initial.getParentNode());
+ for (auto iter = initials.begin(); iter != initials.end(); iter++) {
+ DOMElement* initial = *iter;
+ if (initial->getParentNode() && initial->getParentNode()->getNodeType() == DOMNode::ELEMENT_NODE) {
+ DOMElement* state = static_cast<DOMElement*>(initial->getParentNode());
if (HAS_ATTR(state, "initial")) {
issues.push_back(InterpreterIssue("State with initial attribute cannot have <initial> child ", state, InterpreterIssue::USCXML_ISSUE_WARNING));
}
- if (InterpreterImpl::isAtomic(state)) {
+ if (isAtomic(state)) {
issues.push_back(InterpreterIssue("Atomic state cannot have <initial> child ", state, InterpreterIssue::USCXML_ISSUE_WARNING));
}
}
}
- for (size_t i = 0; i < allStates.size(); i++) {
- Element<std::string> state = Element<std::string>(allStates[i]);
- if (InterpreterImpl::isAtomic(state) && HAS_ATTR(state, "initial")) {
+ for (auto iter = allStates.begin(); iter != allStates.end(); iter++) {
+ DOMElement* state = *iter;
+ if (isAtomic(state) && HAS_ATTR(state, "initial")) {
issues.push_back(InterpreterIssue("Atomic state cannot have initial attribute ", state, InterpreterIssue::USCXML_ISSUE_WARNING));
}
}
- for (size_t i = 0; i < assigns.size(); i++) {
- Element<std::string> assign = Element<std::string>(assigns[i]);
- if (HAS_ATTR(assign, "expr") && assign.getChildNodes().getLength() > 0) {
+ for (auto iter = assigns.begin(); iter != assigns.end(); iter++) {
+ DOMElement* assign = *iter;
+ if (HAS_ATTR(assign, "expr") && assign->getChildNodes()->getLength() > 0) {
issues.push_back(InterpreterIssue("Assign element cannot have expr attribute and children", assign, InterpreterIssue::USCXML_ISSUE_WARNING));
}
}
- for (size_t i = 0; i < contents.size(); i++) {
- Element<std::string> content = Element<std::string>(contents[i]);
- if (HAS_ATTR(content, "expr") && content.getChildNodes().getLength() > 0) {
+ for (auto iter = contents.begin(); iter != contents.end(); iter++) {
+ DOMElement* content = *iter;
+ if (HAS_ATTR(content, "expr") && content->getChildNodes()->getLength() > 0) {
issues.push_back(InterpreterIssue("Content element cannot have expr attribute and children", content, InterpreterIssue::USCXML_ISSUE_WARNING));
}
}
- for (size_t i = 0; i < params.size(); i++) {
- Element<std::string> param = Element<std::string>(params[i]);
+ for (auto iter = params.begin(); iter != params.end(); iter++) {
+ DOMElement* param = *iter;
if (HAS_ATTR(param, "expr") && HAS_ATTR(param, "location")) {
issues.push_back(InterpreterIssue("Param element cannot have both expr and location attribute", param, InterpreterIssue::USCXML_ISSUE_WARNING));
}
}
- for (size_t i = 0; i < scripts.size(); i++) {
- Element<std::string> script = Element<std::string>(scripts[i]);
- if (HAS_ATTR(script, "src") && script.getChildNodes().getLength() > 0) {
+ for (auto iter = scripts.begin(); iter != scripts.end(); iter++) {
+ DOMElement* script = *iter;
+ if (HAS_ATTR(script, "src") && script->getChildNodes()->getLength() > 0) {
issues.push_back(InterpreterIssue("Script element cannot have src attribute and children", script, InterpreterIssue::USCXML_ISSUE_WARNING));
}
}
- for (size_t i = 0; i < sends.size(); i++) {
- Element<std::string> send = Element<std::string>(sends[i]);
+ for (auto iter = sends.begin(); iter != sends.end(); iter++) {
+ DOMElement* send = *iter;
if (HAS_ATTR(send, "event") && HAS_ATTR(send, "eventexpr")) {
issues.push_back(InterpreterIssue("Send element cannot have both event and eventexpr attribute", send, InterpreterIssue::USCXML_ISSUE_WARNING));
}
@@ -723,8 +796,8 @@ NEXT_SET:
issues.push_back(InterpreterIssue("Send element cannot have delay with target _internal", send, InterpreterIssue::USCXML_ISSUE_WARNING));
}
- NodeSet<std::string> contentChilds = DOMUtils::filterChildElements(_nsInfo.xmlNSPrefix + "content", send, false);
- NodeSet<std::string> paramChilds = DOMUtils::filterChildElements(_nsInfo.xmlNSPrefix + "param", send, false);
+ std::list<DOMElement*> contentChilds = DOMUtils::filterChildElements(XML_PREFIX(send).str() + "content", send, false);
+ std::list<DOMElement*> paramChilds = DOMUtils::filterChildElements(XML_PREFIX(send).str() + "param", send, false);
if (HAS_ATTR(send, "namelist") && contentChilds.size() > 0) {
issues.push_back(InterpreterIssue("Send element cannot have namelist attribute and content child", send, InterpreterIssue::USCXML_ISSUE_WARNING));
@@ -735,15 +808,15 @@ NEXT_SET:
}
}
- for (size_t i = 0; i < cancels.size(); i++) {
- Element<std::string> cancel = Element<std::string>(cancels[i]);
+ for (auto iter = cancels.begin(); iter != cancels.end(); iter++) {
+ DOMElement* cancel = *iter;
if (HAS_ATTR(cancel, "sendid") && HAS_ATTR(cancel, "sendidexpr")) {
issues.push_back(InterpreterIssue("Cancel element cannot have both sendid and eventexpr sendidexpr", cancel, InterpreterIssue::USCXML_ISSUE_WARNING));
}
}
- for (size_t i = 0; i < invokes.size(); i++) {
- Element<std::string> invoke = Element<std::string>(invokes[i]);
+ for (auto iter = invokes.begin(); iter != invokes.end(); iter++) {
+ DOMElement* invoke = *iter;
if (HAS_ATTR(invoke, "type") && HAS_ATTR(invoke, "typeexpr")) {
issues.push_back(InterpreterIssue("Invoke element cannot have both type and typeexpr attribute", invoke, InterpreterIssue::USCXML_ISSUE_WARNING));
}
@@ -753,18 +826,18 @@ NEXT_SET:
if (HAS_ATTR(invoke, "id") && HAS_ATTR(invoke, "idlocation")) {
issues.push_back(InterpreterIssue("Invoke element cannot have both id and idlocation attribute", invoke, InterpreterIssue::USCXML_ISSUE_WARNING));
}
- if (HAS_ATTR(invoke, "namelist") && DOMUtils::filterChildElements(_nsInfo.xmlNSPrefix + "param", invoke, false).size() > 0) {
+ if (HAS_ATTR(invoke, "namelist") && DOMUtils::filterChildElements(XML_PREFIX(invoke).str() + "param", invoke, false).size() > 0) {
issues.push_back(InterpreterIssue("Invoke element cannot have namelist attribute and param child", invoke, InterpreterIssue::USCXML_ISSUE_WARNING));
}
- if (HAS_ATTR(invoke, "src") && DOMUtils::filterChildElements(_nsInfo.xmlNSPrefix + "content", invoke, false).size() > 0) {
+ if (HAS_ATTR(invoke, "src") && DOMUtils::filterChildElements(XML_PREFIX(invoke).str() + "content", invoke, false).size() > 0) {
issues.push_back(InterpreterIssue("Invoke element cannot have src attribute and content child", invoke, InterpreterIssue::USCXML_ISSUE_WARNING));
}
}
- for (size_t i = 0; i < doneDatas.size(); i++) {
- Element<std::string> donedata = Element<std::string>(doneDatas[i]);
- if (DOMUtils::filterChildElements(_nsInfo.xmlNSPrefix + "content", donedata, false).size() > 0 &&
- DOMUtils::filterChildElements(_nsInfo.xmlNSPrefix + "param", donedata, false).size() > 0) {
+ for (auto iter = doneDatas.begin(); iter != doneDatas.end(); iter++) {
+ DOMElement* donedata = *iter;
+ if (DOMUtils::filterChildElements(XML_PREFIX(donedata).str() + "content", donedata, false).size() > 0 &&
+ DOMUtils::filterChildElements(XML_PREFIX(donedata).str() + "param", donedata, false).size() > 0) {
issues.push_back(InterpreterIssue("Donedata element cannot have param child and content child", donedata, InterpreterIssue::USCXML_ISSUE_WARNING));
}
@@ -798,15 +871,15 @@ NEXT_SET:
// test all scripts for valid syntax
{
- for (size_t i = 0; i < scripts.size(); i++) {
- Element<std::string> script = Element<std::string>(scripts[i]);
+ for (auto iter = scripts.begin(); iter != scripts.end(); iter++) {
+ DOMElement* script = *iter;
- if (script.hasChildNodes()) {
+ if (script->hasChildNodes()) {
// search for the text node with the actual script
std::string scriptContent;
- for (Node<std::string> child = script.getFirstChild(); child; child = child.getNextSibling()) {
- if (child.getNodeType() == Node_base::TEXT_NODE || child.getNodeType() == Node_base::CDATA_SECTION_NODE)
- scriptContent += child.getNodeValue();
+ for (DOMNode* child = script->getFirstChild(); child; child = child->getNextSibling()) {
+ if (child->getNodeType() == DOMNode::TEXT_NODE || child->getNodeType() == DOMNode::CDATA_SECTION_NODE)
+ scriptContent += (std::string)X(child->getNodeValue());
}
if (!_dataModel.isValidSyntax(scriptContent)) {
@@ -818,13 +891,13 @@ NEXT_SET:
// test the various attributes with datamodel expressions for valid syntax
{
- NodeSet<std::string> withCondAttrs;
- withCondAttrs.push_back(transitions);
- withCondAttrs.push_back(ifs);
- withCondAttrs.push_back(elseIfs);
+ std::list<DOMElement*> withCondAttrs;
+ withCondAttrs.insert(withCondAttrs.end(), transitions.begin(), transitions.end());
+ withCondAttrs.insert(withCondAttrs.end(), ifs.begin(), ifs.end());
+ withCondAttrs.insert(withCondAttrs.end(), elseIfs.begin(), elseIfs.end());
- for (size_t i = 0; i < withCondAttrs.size(); i++) {
- Element<std::string> condAttr = Element<std::string>(withCondAttrs[i]);
+ for (auto iter = withCondAttrs.begin(); iter != withCondAttrs.end(); iter++) {
+ DOMElement* condAttr = *iter;
if (HAS_ATTR(condAttr, "cond")) {
if (!_dataModel.isValidSyntax(ATTR(condAttr, "cond"))) {
issues.push_back(InterpreterIssue("Syntax error in cond attribute", condAttr, InterpreterIssue::USCXML_ISSUE_WARNING));
@@ -835,17 +908,17 @@ NEXT_SET:
}
{
- NodeSet<std::string> withExprAttrs;
- withExprAttrs.push_back(logs);
- withExprAttrs.push_back(datas);
- withExprAttrs.push_back(assigns);
- withExprAttrs.push_back(contents);
- withExprAttrs.push_back(params);
-
- for (size_t i = 0; i < withExprAttrs.size(); i++) {
- Element<std::string> withExprAttr = Element<std::string>(withExprAttrs[i]);
+ std::list<DOMElement*> withExprAttrs;
+ withExprAttrs.insert(withExprAttrs.end(), logs.begin(), logs.end());
+ withExprAttrs.insert(withExprAttrs.end(), datas.begin(), datas.end());
+ withExprAttrs.insert(withExprAttrs.end(), assigns.begin(), assigns.end());
+ withExprAttrs.insert(withExprAttrs.end(), contents.begin(), contents.end());
+ withExprAttrs.insert(withExprAttrs.end(), params.begin(), params.end());
+
+ for (auto iter = withExprAttrs.begin(); iter != withExprAttrs.end(); iter++) {
+ DOMElement* withExprAttr = *iter;
if (HAS_ATTR(withExprAttr, "expr")) {
- if (InterpreterImpl::isMember(withExprAttr, datas) || InterpreterImpl::isMember(withExprAttr, assigns)) {
+ if (DOMUtils::isMember(withExprAttr, datas) || DOMUtils::isMember(withExprAttr, assigns)) {
if (!_dataModel.isValidSyntax("foo = " + ATTR(withExprAttr, "expr"))) { // TODO: this is ECMAScripty!
issues.push_back(InterpreterIssue("Syntax error in expr attribute", withExprAttr, InterpreterIssue::USCXML_ISSUE_WARNING));
continue;
@@ -861,8 +934,8 @@ NEXT_SET:
}
{
- for (size_t i = 0; i < foreachs.size(); i++) {
- Element<std::string> foreach = Element<std::string>(foreachs[i]);
+ for (auto iter = foreachs.begin(); iter != foreachs.end(); iter++) {
+ DOMElement* foreach = *iter;
if (HAS_ATTR(foreach, "array")) {
if (!_dataModel.isValidSyntax(ATTR(foreach, "array"))) {
issues.push_back(InterpreterIssue("Syntax error in array attribute", foreach, InterpreterIssue::USCXML_ISSUE_WARNING));
@@ -882,8 +955,8 @@ NEXT_SET:
}
{
- for (size_t i = 0; i < sends.size(); i++) {
- Element<std::string> send = Element<std::string>(sends[i]);
+ for (auto iter = sends.begin(); iter != sends.end(); iter++) {
+ DOMElement* send = *iter;
if (HAS_ATTR(send, "eventexpr")) {
if (!_dataModel.isValidSyntax(ATTR(send, "eventexpr"))) {
issues.push_back(InterpreterIssue("Syntax error in eventexpr attribute", send, InterpreterIssue::USCXML_ISSUE_WARNING));
@@ -914,8 +987,8 @@ NEXT_SET:
}
{
- for (size_t i = 0; i < invokes.size(); i++) {
- Element<std::string> invoke = Element<std::string>(invokes[i]);
+ for (auto iter = invokes.begin(); iter != invokes.end(); iter++) {
+ DOMElement* invoke = *iter;
if (HAS_ATTR(invoke, "typeexpr")) {
if (!_dataModel.isValidSyntax(ATTR(invoke, "typeexpr"))) {
issues.push_back(InterpreterIssue("Syntax error in typeexpr attribute", invoke, InterpreterIssue::USCXML_ISSUE_WARNING));
@@ -938,8 +1011,8 @@ NEXT_SET:
}
{
- for (size_t i = 0; i < cancels.size(); i++) {
- Element<std::string> cancel = Element<std::string>(cancels[i]);
+ for (auto iter = cancels.begin(); iter != cancels.end(); iter++) {
+ DOMElement* cancel = *iter;
if (HAS_ATTR(cancel, "sendidexpr")) {
if (!_dataModel.isValidSyntax(ATTR(cancel, "sendidexpr"))) {
issues.push_back(InterpreterIssue("Syntax error in sendidexpr attribute", cancel, InterpreterIssue::USCXML_ISSUE_WARNING));
@@ -955,5 +1028,29 @@ NEXT_SET:
return issues;
}
+std::ostream& operator<< (std::ostream& os, const InterpreterIssue& issue) {
+ switch (issue.severity) {
+ case InterpreterIssue::USCXML_ISSUE_FATAL:
+ os << "Issue (FATAL) ";
+ break;
+ case InterpreterIssue::USCXML_ISSUE_WARNING:
+ os << "Issue (WARNING) ";
+ break;
+ case InterpreterIssue::USCXML_ISSUE_INFO:
+ os << "Issue (INFO) ";
+ break;
+ default:
+ break;
+ }
+
+ if (issue.xPath.size() > 0) {
+ os << "at " << issue.xPath << ": ";
+ } else {
+ os << ": ";
+ }
+ os << issue.message;
+ return os;
+}
+
} \ No newline at end of file