summaryrefslogtreecommitdiffstats
path: root/src/uscxml/debug
diff options
context:
space:
mode:
authorStefan Radomski <sradomski@mintwerk.de>2016-01-10 02:40:12 (GMT)
committerStefan Radomski <sradomski@mintwerk.de>2016-01-10 02:40:12 (GMT)
commit613cf9fb6fe4b24bc7852d5a31953f6ff419e43c (patch)
tree8459365c5a6a00503063b0bf1d516fce5ea4d891 /src/uscxml/debug
parentc699a4057a65a9a09f78310d8e12588f2dc072cd (diff)
downloaduscxml-613cf9fb6fe4b24bc7852d5a31953f6ff419e43c.zip
uscxml-613cf9fb6fe4b24bc7852d5a31953f6ff419e43c.tar.gz
uscxml-613cf9fb6fe4b24bc7852d5a31953f6ff419e43c.tar.bz2
Beautified code
Diffstat (limited to 'src/uscxml/debug')
-rw-r--r--src/uscxml/debug/Complexity.cpp56
-rw-r--r--src/uscxml/debug/Complexity.h22
-rw-r--r--src/uscxml/debug/InterpreterIssue.cpp620
-rw-r--r--src/uscxml/debug/InterpreterIssue.h6
4 files changed, 353 insertions, 351 deletions
diff --git a/src/uscxml/debug/Complexity.cpp b/src/uscxml/debug/Complexity.cpp
index de01831..29d7706 100644
--- a/src/uscxml/debug/Complexity.cpp
+++ b/src/uscxml/debug/Complexity.cpp
@@ -33,15 +33,15 @@ std::list<std::set<Element<std::string> > > Complexity::getAllConfigurations(con
std::string nsPrefix = (root.getPrefix().size() > 0 ? root.getPrefix() + ":" : "");
std::string localName = root.getLocalName();
bool isAtomic = true;
-
+
NodeList<std::string> children = root.getChildNodes();
for (int i = 0; i < children.getLength(); i++) {
if (children.item(i).getNodeType() != Node_base::ELEMENT_NODE)
continue;
Element<std::string> childElem(children.item(i));
if (childElem.getTagName() == nsPrefix + "state" ||
- childElem.getTagName() == nsPrefix + "parallel" ||
- childElem.getTagName() == nsPrefix + "final") {
+ childElem.getTagName() == nsPrefix + "parallel" ||
+ childElem.getTagName() == nsPrefix + "final") {
// nested child state
std::list<std::set<Element<std::string> > > nestedConfigurations = getAllConfigurations(childElem);
isAtomic = false;
@@ -50,7 +50,7 @@ std::list<std::set<Element<std::string> > > Complexity::getAllConfigurations(con
std::list<std::set<Element<std::string> > > combinedConfigurations;
for (std::list<std::set<Element<std::string> > >::iterator existIter = allConfigurations.begin(); existIter != allConfigurations.end(); existIter++) {
std::set<Element<std::string> > existingConfig = *existIter;
-
+
for (std::list<std::set<Element<std::string> > >::iterator newIter = nestedConfigurations.begin(); newIter != nestedConfigurations.end(); newIter++) {
std::set<Element<std::string> > newConfig = *newIter;
@@ -81,13 +81,13 @@ std::list<std::set<Element<std::string> > > Complexity::getAllConfigurations(con
}
return allConfigurations;
}
-
+
std::map<size_t, size_t> Complexity::getTransitionHistogramm(const Arabica::DOM::Element<std::string>& root) {
std::map<size_t, size_t> histogram;
std::string nameSpace;
-
+
std::list<std::set<Element<std::string> > > allConfig = Complexity::getAllConfigurations(root);
-
+
// for every legal configuration, count the transitions
for (std::list<std::set<Element<std::string> > >::iterator confIter = allConfig.begin(); confIter != allConfig.end(); confIter++) {
NodeSet<std::string> configNodeSet;
@@ -106,29 +106,29 @@ std::map<size_t, size_t> Complexity::getTransitionHistogramm(const Arabica::DOM:
uint64_t Complexity::stateMachineComplexity(InterpreterImpl* interpreter, Variant variant) {
- Arabica::DOM::Element<std::string> root = interpreter->getDocument().getDocumentElement();
-
- Arabica::XPath::NodeSet<std::string> reachable;
-
- if (variant & IGNORE_UNREACHABLE) {
- reachable = interpreter->getReachableStates();
- }
-
- Complexity complexity = calculateStateMachineComplexity(root, reachable);
+ Arabica::DOM::Element<std::string> root = interpreter->getDocument().getDocumentElement();
+
+ Arabica::XPath::NodeSet<std::string> reachable;
+
+ if (variant & IGNORE_UNREACHABLE) {
+ reachable = interpreter->getReachableStates();
+ }
+
+ Complexity complexity = calculateStateMachineComplexity(root, reachable);
uint64_t value = complexity.value;
-
- if (!(variant & IGNORE_HISTORY)) {
+
+ if (!(variant & IGNORE_HISTORY)) {
for (std::list<uint64_t>::const_iterator histIter = complexity.history.begin(); histIter != complexity.history.end(); histIter++) {
value *= *histIter;
}
}
-
- if (!(variant & IGNORE_NESTED_DATA)) {
+
+ if (!(variant & IGNORE_NESTED_DATA)) {
bool ignoreNestedData = false;
if (root.getLocalName() == "scxml" && (!HAS_ATTR_CAST(root, "binding") || boost::to_lower_copy(ATTR_CAST(root, "binding")) == "early")) {
ignoreNestedData = true;
}
-
+
if (!ignoreNestedData) {
uint64_t power = complexity.nestedData;
while(power--) {
@@ -136,17 +136,17 @@ uint64_t Complexity::stateMachineComplexity(InterpreterImpl* interpreter, Varian
}
}
}
-
+
return value;
}
-
+
Complexity Complexity::calculateStateMachineComplexity(const Arabica::DOM::Element<std::string>& root, const Arabica::XPath::NodeSet<std::string>& reachable) {
Complexity complexity;
bool hasFlatHistory = false;
bool hasDeepHistory = false;
bool hasNestedData = false;
-
+
Arabica::DOM::NodeList<std::string> childElems = root.getChildNodes();
for (int i = 0; i < childElems.getLength(); i++) {
if (childElems.item(i).getNodeType() != Node_base::ELEMENT_NODE)
@@ -170,10 +170,10 @@ Complexity Complexity::calculateStateMachineComplexity(const Arabica::DOM::Eleme
if (hasNestedData)
complexity.nestedData++;
-
- if (reachable.size() > 0 && !InterpreterImpl::isMember(root, reachable)) {
- return 0;
- } else if (InterpreterImpl::isCompound(root) || TAGNAME(root) == "scxml") {
+
+ if (reachable.size() > 0 && !InterpreterImpl::isMember(root, reachable)) {
+ return 0;
+ } else if (InterpreterImpl::isCompound(root) || TAGNAME(root) == "scxml") {
// compounds can be in any of the child state -> add
NodeSet<std::string> childs = InterpreterImpl::getChildStates(root);
for (int i = 0; i < childs.size(); i++) {
diff --git a/src/uscxml/debug/Complexity.h b/src/uscxml/debug/Complexity.h
index 76330fd..de05692 100644
--- a/src/uscxml/debug/Complexity.h
+++ b/src/uscxml/debug/Complexity.h
@@ -27,35 +27,35 @@ namespace uscxml {
class USCXML_API Complexity {
public:
-
+
enum Variant {
IGNORE_NOTHING = 0x0000,
IGNORE_HISTORY = 0x0001,
IGNORE_NESTED_DATA = 0x0002,
IGNORE_UNREACHABLE = 0x0004,
};
-
+
Complexity() : value(0), nestedData(0) {}
Complexity(uint64_t value) : value(value), nestedData(0) {}
-
+
Complexity& operator+=(const Complexity& rhs) {
value += rhs.value;
nestedData += rhs.nestedData;
history.insert(history.end(), rhs.history.begin(), rhs.history.end());
return *this;
}
-
+
Complexity& operator*=(const Complexity& rhs) {
value *= rhs.value;
nestedData += rhs.nestedData;
history.insert(history.end(), rhs.history.begin(), rhs.history.end());
return *this;
}
-
- static uint64_t stateMachineComplexity(const Interpreter& interpreter, Complexity::Variant variant = IGNORE_NOTHING) {
- return stateMachineComplexity(interpreter.getImpl().get());
- }
- static uint64_t stateMachineComplexity(InterpreterImpl* interpreter, Complexity::Variant variant = IGNORE_NOTHING);
+
+ static uint64_t stateMachineComplexity(const Interpreter& interpreter, Complexity::Variant variant = IGNORE_NOTHING) {
+ return stateMachineComplexity(interpreter.getImpl().get());
+ }
+ static uint64_t stateMachineComplexity(InterpreterImpl* interpreter, Complexity::Variant variant = IGNORE_NOTHING);
static std::list<std::set<Arabica::DOM::Element<std::string> > > getAllConfigurations(const Arabica::DOM::Element<std::string>& root);
static std::map<size_t, size_t> getTransitionHistogramm(const Arabica::DOM::Element<std::string>& root);
@@ -69,8 +69,8 @@ protected:
};
inline Complexity::Variant operator | ( Complexity::Variant lhs, Complexity::Variant rhs ) {
- // Cast to int first otherwise we'll just end up recursing
- return static_cast< Complexity::Variant >( static_cast< int >( lhs ) | static_cast< int >( rhs ) );
+ // Cast to int first otherwise we'll just end up recursing
+ return static_cast< Complexity::Variant >( static_cast< int >( lhs ) | static_cast< int >( rhs ) );
}
}
diff --git a/src/uscxml/debug/InterpreterIssue.cpp b/src/uscxml/debug/InterpreterIssue.cpp
index 49b595d..7d55f3a 100644
--- a/src/uscxml/debug/InterpreterIssue.cpp
+++ b/src/uscxml/debug/InterpreterIssue.cpp
@@ -59,35 +59,36 @@ void assembleNodeSets(const std::string nsPrefix, const Node<std::string>& node,
* Can the given states ever appear in an active configuration?
*/
bool hasLegalCompletion(const NodeSet<std::string>& states) {
- if (states.size() < 2)
- return true;
-
- // iterate every pair
- for (unsigned int outer = 0; outer < states.size() - 1; outer++) {
- Element<std::string> s1(states[outer]);
- for (unsigned int inner = outer + 1; inner < states.size(); inner++) {
- Element<std::string> s2(states[inner]);
- Node<std::string> parent;
-
- // ok to be directly ancestorally related
- if (InterpreterImpl::isDescendant(s1, s2) || InterpreterImpl::isDescendant(s2, s1))
- goto NEXT_PAIR;
-
- // find least common ancestor
- parent = s1.getParentNode();
- while(parent && parent.getNodeType() == Node_base::ELEMENT_NODE) {
- if (InterpreterImpl::isDescendant(s2, parent)) {
- if (InterpreterImpl::isParallel(Element<std::string>(parent)))
- goto NEXT_PAIR;
- }
- parent = parent.getParentNode();
- }
-
- return false;
- NEXT_PAIR:;
- }
- }
- return true;
+ if (states.size() < 2)
+ return true;
+
+ // iterate every pair
+ for (unsigned int outer = 0; outer < states.size() - 1; outer++) {
+ Element<std::string> s1(states[outer]);
+ for (unsigned int inner = outer + 1; inner < states.size(); inner++) {
+ Element<std::string> s2(states[inner]);
+ Node<std::string> parent;
+
+ // ok to be directly ancestorally related
+ if (InterpreterImpl::isDescendant(s1, s2) || InterpreterImpl::isDescendant(s2, s1))
+ goto NEXT_PAIR;
+
+ // find least common ancestor
+ parent = s1.getParentNode();
+ while(parent && parent.getNodeType() == Node_base::ELEMENT_NODE) {
+ if (InterpreterImpl::isDescendant(s2, parent)) {
+ if (InterpreterImpl::isParallel(Element<std::string>(parent)))
+ goto NEXT_PAIR;
+ }
+ parent = parent.getParentNode();
+ }
+
+ return false;
+NEXT_PAIR:
+ ;
+ }
+ }
+ return true;
}
std::list<InterpreterIssue> InterpreterIssue::forInterpreter(InterpreterImpl* interpreter) {
@@ -170,8 +171,8 @@ std::list<InterpreterIssue> InterpreterIssue::forInterpreter(InterpreterImpl* in
allExecContents.push_back(cancels);
NodeSet<std::string> allElements;
- allElements.push_back(scxmls);
- allElements.push_back(allStates);
+ allElements.push_back(scxmls);
+ allElements.push_back(allStates);
allElements.push_back(allExecContents);
allElements.push_back(transitions);
allElements.push_back(initials);
@@ -191,26 +192,26 @@ std::list<InterpreterIssue> InterpreterIssue::forInterpreter(InterpreterImpl* in
execContentSet.insert("elseif");
execContentSet.insert("else");
execContentSet.insert("foreach");
- execContentSet.insert("raise");
+ execContentSet.insert("raise");
execContentSet.insert("send");
- execContentSet.insert("cancel");
+ execContentSet.insert("cancel");
execContentSet.insert("assign");
execContentSet.insert("script");
- execContentSet.insert("log");
-
- // required attributes per standard
- std::map<std::string, std::set<std::string> > reqAttr;
- reqAttr["scxml"].insert("xmlns");
- reqAttr["scxml"].insert("version");
- reqAttr["raise"].insert("event");
- reqAttr["if"].insert("cond");
- reqAttr["elseif"].insert("cond");
- reqAttr["foreach"].insert("array");
- reqAttr["foreach"].insert("item");
- reqAttr["data"].insert("id");
- reqAttr["assign"].insert("location");
- reqAttr["param"].insert("name");
-
+ execContentSet.insert("log");
+
+ // required attributes per standard
+ std::map<std::string, std::set<std::string> > reqAttr;
+ reqAttr["scxml"].insert("xmlns");
+ reqAttr["scxml"].insert("version");
+ reqAttr["raise"].insert("event");
+ reqAttr["if"].insert("cond");
+ reqAttr["elseif"].insert("cond");
+ reqAttr["foreach"].insert("array");
+ reqAttr["foreach"].insert("item");
+ reqAttr["data"].insert("id");
+ reqAttr["assign"].insert("location");
+ reqAttr["param"].insert("name");
+
// these are the valid children for elements in the SCXML namespace as per specification
std::map<std::string, std::set<std::string> > validChildren;
validChildren["scxml"].insert("state");
@@ -224,11 +225,11 @@ std::list<InterpreterIssue> InterpreterIssue::forInterpreter(InterpreterImpl* in
validChildren["state"].insert("transition");
validChildren["state"].insert("state");
validChildren["state"].insert("parallel");
- validChildren["state"].insert("history");
- validChildren["state"].insert("datamodel");
- validChildren["state"].insert("invoke");
- validChildren["state"].insert("initial");
- validChildren["state"].insert("final");
+ validChildren["state"].insert("history");
+ validChildren["state"].insert("datamodel");
+ validChildren["state"].insert("invoke");
+ validChildren["state"].insert("initial");
+ validChildren["state"].insert("final");
validChildren["parallel"].insert("onentry");
validChildren["parallel"].insert("onexit");
@@ -351,7 +352,7 @@ std::list<InterpreterIssue> InterpreterIssue::forInterpreter(InterpreterImpl* in
if (targetIds.size() == 0) {
issues.push_back(InterpreterIssue("Transition has empty target state list", transition, InterpreterIssue::USCXML_ISSUE_FATAL));
}
-
+
for (std::list<std::string>::iterator targetIter = targetIds.begin(); targetIter != targetIds.end(); targetIter++) {
if (seenStates.find(*targetIter) == seenStates.end()) {
issues.push_back(InterpreterIssue("Transition has non-existant target state with id '" + *targetIter + "'", transition, InterpreterIssue::USCXML_ISSUE_FATAL));
@@ -405,25 +406,25 @@ NEXT_TRANSITION:
}
}
- // check for useless history elements
- {
- for (int i = 0; i < histories.size(); i++) {
- Element<std::string> history = Element<std::string>(histories[i]);
- if (!history.getParentNode() || history.getParentNode().getNodeType() != Node_base::ELEMENT_NODE)
- continue; // syntax check will have catched this
- Element<std::string> parent(history.getParentNode());
- if (InterpreterImpl::isAtomic(parent)) {
- issues.push_back(InterpreterIssue("Useless history '" + ATTR(history, "id") + "' in atomic state", history, InterpreterIssue::USCXML_ISSUE_INFO));
- continue;
- }
- std::list<std::set<Arabica::DOM::Element<std::string> > > configs = Complexity::getAllConfigurations(parent);
- if (configs.size() <= 1) {
- issues.push_back(InterpreterIssue("Useless history '" + ATTR(history, "id") + "' in state with single legal configuration", history, InterpreterIssue::USCXML_ISSUE_INFO));
- continue;
- }
- }
- }
-
+ // check for useless history elements
+ {
+ for (int i = 0; i < histories.size(); i++) {
+ Element<std::string> history = Element<std::string>(histories[i]);
+ if (!history.getParentNode() || history.getParentNode().getNodeType() != Node_base::ELEMENT_NODE)
+ continue; // syntax check will have catched this
+ Element<std::string> parent(history.getParentNode());
+ if (InterpreterImpl::isAtomic(parent)) {
+ issues.push_back(InterpreterIssue("Useless history '" + ATTR(history, "id") + "' in atomic state", history, InterpreterIssue::USCXML_ISSUE_INFO));
+ continue;
+ }
+ std::list<std::set<Arabica::DOM::Element<std::string> > > configs = Complexity::getAllConfigurations(parent);
+ if (configs.size() <= 1) {
+ issues.push_back(InterpreterIssue("Useless history '" + ATTR(history, "id") + "' in state with single legal configuration", history, InterpreterIssue::USCXML_ISSUE_INFO));
+ continue;
+ }
+ }
+ }
+
// check for valid initial attribute
{
NodeSet<std::string> withInitialAttr;
@@ -434,121 +435,122 @@ NEXT_TRANSITION:
Element<std::string> state = Element<std::string>(withInitialAttr[i]);
if (HAS_ATTR(state, "initial")) {
- NodeSet<std::string> childs;
- childs.push_back(InterpreterImpl::filterChildElements(_nsInfo.xmlNSPrefix + "state", state, true));
- childs.push_back(InterpreterImpl::filterChildElements(_nsInfo.xmlNSPrefix + "parallel", state, true));
- childs.push_back(InterpreterImpl::filterChildElements(_nsInfo.xmlNSPrefix + "final", state, true));
- childs.push_back(InterpreterImpl::filterChildElements(_nsInfo.xmlNSPrefix + "history", state, true));
+ NodeSet<std::string> childs;
+ childs.push_back(InterpreterImpl::filterChildElements(_nsInfo.xmlNSPrefix + "state", state, true));
+ childs.push_back(InterpreterImpl::filterChildElements(_nsInfo.xmlNSPrefix + "parallel", state, true));
+ childs.push_back(InterpreterImpl::filterChildElements(_nsInfo.xmlNSPrefix + "final", state, true));
+ childs.push_back(InterpreterImpl::filterChildElements(_nsInfo.xmlNSPrefix + "history", state, true));
- std::list<std::string> intials = InterpreterImpl::tokenizeIdRefs(ATTR(state, "initial"));
+ std::list<std::string> intials = InterpreterImpl::tokenizeIdRefs(ATTR(state, "initial"));
for (std::list<std::string>::iterator initIter = intials.begin(); initIter != intials.end(); initIter++) {
if (seenStates.find(*initIter) == seenStates.end()) {
issues.push_back(InterpreterIssue("Initial attribute has invalid target state with id '" + *initIter + "'", state, InterpreterIssue::USCXML_ISSUE_FATAL));
continue;
}
- // value of the 'initial' attribute [..] must be descendants of the containing <state> or <parallel> element
- if (!InterpreterImpl::isMember(seenStates[*initIter], childs)) {
- issues.push_back(InterpreterIssue("Initial attribute references non-child state '" + *initIter + "'", state, InterpreterIssue::USCXML_ISSUE_FATAL));
- }
+ // value of the 'initial' attribute [..] must be descendants of the containing <state> or <parallel> element
+ if (!InterpreterImpl::isMember(seenStates[*initIter], childs)) {
+ issues.push_back(InterpreterIssue("Initial attribute references non-child state '" + *initIter + "'", state, InterpreterIssue::USCXML_ISSUE_FATAL));
+ }
}
}
}
}
- // check for legal configuration of target sets
- {
- std::map<Element<std::string>, std::string > targetIdSets;
- for (int i = 0; i < transitions.size(); i++) {
- Element<std::string> transition = Element<std::string>(transitions[i]);
-
- if (HAS_ATTR(transition, "target")) {
- targetIdSets[transition] = ATTR(transition, "target");
- }
- }
-
- for (int i = 0; i < initials.size(); i++) {
- Element<std::string> initial = Element<std::string>(initials[i]);
-
- if (HAS_ATTR(initial, "target")) {
- targetIdSets[initial] = ATTR(initial, "target");
- }
- }
-
- for (int i = 0; i < allStates.size(); i++) {
- Element<std::string> state = Element<std::string>(allStates[i]);
-
- if (HAS_ATTR(state, "initial")) {
- targetIdSets[state] = ATTR(state, "initial");
- }
- }
-
- for (std::map<Element<std::string>, std::string >::iterator setIter = targetIdSets.begin();
- setIter != targetIdSets.end();
- setIter++) {
- NodeSet<std::string> targets;
- std::list<std::string> targetIds = InterpreterImpl::tokenizeIdRefs(setIter->second);
- for (std::list<std::string>::iterator tgtIter = targetIds.begin(); tgtIter != targetIds.end(); tgtIter++) {
- if (seenStates.find(*tgtIter) == seenStates.end())
- goto NEXT_SET;
- targets.push_back(seenStates[*tgtIter]);
- }
- if (!hasLegalCompletion(targets)) {
- issues.push_back(InterpreterIssue("Target states cause illegal configuration", setIter->first, InterpreterIssue::USCXML_ISSUE_FATAL));
- }
- NEXT_SET:;
- }
- }
-
- // check for valid initial transition
- {
- NodeSet<std::string> initTrans;
+ // check for legal configuration of target sets
+ {
+ std::map<Element<std::string>, std::string > targetIdSets;
+ for (int i = 0; i < transitions.size(); i++) {
+ Element<std::string> transition = Element<std::string>(transitions[i]);
+
+ if (HAS_ATTR(transition, "target")) {
+ targetIdSets[transition] = ATTR(transition, "target");
+ }
+ }
+
+ for (int i = 0; i < initials.size(); i++) {
+ Element<std::string> initial = Element<std::string>(initials[i]);
+
+ if (HAS_ATTR(initial, "target")) {
+ targetIdSets[initial] = ATTR(initial, "target");
+ }
+ }
+
+ for (int i = 0; i < allStates.size(); i++) {
+ Element<std::string> state = Element<std::string>(allStates[i]);
+
+ if (HAS_ATTR(state, "initial")) {
+ targetIdSets[state] = ATTR(state, "initial");
+ }
+ }
+
+ for (std::map<Element<std::string>, std::string >::iterator setIter = targetIdSets.begin();
+ setIter != targetIdSets.end();
+ setIter++) {
+ NodeSet<std::string> targets;
+ std::list<std::string> targetIds = InterpreterImpl::tokenizeIdRefs(setIter->second);
+ for (std::list<std::string>::iterator tgtIter = targetIds.begin(); tgtIter != targetIds.end(); tgtIter++) {
+ if (seenStates.find(*tgtIter) == seenStates.end())
+ goto NEXT_SET;
+ targets.push_back(seenStates[*tgtIter]);
+ }
+ if (!hasLegalCompletion(targets)) {
+ issues.push_back(InterpreterIssue("Target states cause illegal configuration", setIter->first, InterpreterIssue::USCXML_ISSUE_FATAL));
+ }
+NEXT_SET:
+ ;
+ }
+ }
+
+ // check for valid initial transition
+ {
+ NodeSet<std::string> initTrans;
// initTrans.push_back(InterpreterImpl::filterChildElements(_nsInfo.xmlNSPrefix + "transition", histories, true));
-
- for (int i = 0; i < initials.size(); i++) {
- Element<std::string> initial = Element<std::string>(initials[i]);
- NodeSet<std::string> initTransitions = InterpreterImpl::filterChildElements(_nsInfo.xmlNSPrefix + "transition", initial, true);
- if (initTransitions.size() != 1) {
- issues.push_back(InterpreterIssue("Initial element must define exactly one transition", initial, InterpreterIssue::USCXML_ISSUE_FATAL));
- }
- initTrans.push_back(initTransitions);
-
- }
-
- for (int i = 0; i < initTrans.size(); i++) {
- Element<std::string> transition = Element<std::string>(initTrans[i]);
-
- /* In a conformant SCXML document, this transition must not contain 'cond' or 'event' attributes, and must specify a non-null 'target'
- * whose value is a valid state specification consisting solely of descendants of the containing state
- */
-
- if (HAS_ATTR(transition, "cond")) {
- issues.push_back(InterpreterIssue("Initial transition cannot have a condition", transition, InterpreterIssue::USCXML_ISSUE_FATAL));
- }
- if (HAS_ATTR(transition, "event")) {
- issues.push_back(InterpreterIssue("Initial transition cannot be eventful", transition, InterpreterIssue::USCXML_ISSUE_FATAL));
- }
-
- if (!transition.getParentNode() || !transition.getParentNode().getParentNode() || transition.getParentNode().getParentNode().getNodeType() != Node_base::ELEMENT_NODE)
- continue; // syntax will catch this one
- Element<std::string> state(transition.getParentNode().getParentNode());
- if (!InterpreterImpl::isState(state))
- continue; // syntax will catch this one
-
- NodeSet<std::string> childs;
- childs.push_back(InterpreterImpl::filterChildElements(_nsInfo.xmlNSPrefix + "state", state, true));
- childs.push_back(InterpreterImpl::filterChildElements(_nsInfo.xmlNSPrefix + "parallel", state, true));
- childs.push_back(InterpreterImpl::filterChildElements(_nsInfo.xmlNSPrefix + "final", state, true));
- childs.push_back(InterpreterImpl::filterChildElements(_nsInfo.xmlNSPrefix + "history", state, true));
-
- std::list<std::string> intials = InterpreterImpl::tokenizeIdRefs(ATTR(transition, "target"));
- for (std::list<std::string>::iterator initIter = intials.begin(); initIter != intials.end(); initIter++) {
- // the 'target' of a <transition> inside an <initial> or <history> element: all the states must be descendants of the containing <state> or <parallel> element
- if (!InterpreterImpl::isMember(seenStates[*initIter], childs)) {
- issues.push_back(InterpreterIssue("Target of initial transition references non-child state '" + *initIter + "'", transition, InterpreterIssue::USCXML_ISSUE_FATAL));
- }
- }
- }
- }
+
+ for (int i = 0; i < initials.size(); i++) {
+ Element<std::string> initial = Element<std::string>(initials[i]);
+ NodeSet<std::string> initTransitions = InterpreterImpl::filterChildElements(_nsInfo.xmlNSPrefix + "transition", initial, true);
+ if (initTransitions.size() != 1) {
+ issues.push_back(InterpreterIssue("Initial element must define exactly one transition", initial, InterpreterIssue::USCXML_ISSUE_FATAL));
+ }
+ initTrans.push_back(initTransitions);
+
+ }
+
+ for (int i = 0; i < initTrans.size(); i++) {
+ Element<std::string> transition = Element<std::string>(initTrans[i]);
+
+ /* In a conformant SCXML document, this transition must not contain 'cond' or 'event' attributes, and must specify a non-null 'target'
+ * whose value is a valid state specification consisting solely of descendants of the containing state
+ */
+
+ if (HAS_ATTR(transition, "cond")) {
+ issues.push_back(InterpreterIssue("Initial transition cannot have a condition", transition, InterpreterIssue::USCXML_ISSUE_FATAL));
+ }
+ if (HAS_ATTR(transition, "event")) {
+ issues.push_back(InterpreterIssue("Initial transition cannot be eventful", transition, InterpreterIssue::USCXML_ISSUE_FATAL));
+ }
+
+ if (!transition.getParentNode() || !transition.getParentNode().getParentNode() || transition.getParentNode().getParentNode().getNodeType() != Node_base::ELEMENT_NODE)
+ continue; // syntax will catch this one
+ Element<std::string> state(transition.getParentNode().getParentNode());
+ if (!InterpreterImpl::isState(state))
+ continue; // syntax will catch this one
+
+ NodeSet<std::string> childs;
+ childs.push_back(InterpreterImpl::filterChildElements(_nsInfo.xmlNSPrefix + "state", state, true));
+ childs.push_back(InterpreterImpl::filterChildElements(_nsInfo.xmlNSPrefix + "parallel", state, true));
+ childs.push_back(InterpreterImpl::filterChildElements(_nsInfo.xmlNSPrefix + "final", state, true));
+ childs.push_back(InterpreterImpl::filterChildElements(_nsInfo.xmlNSPrefix + "history", state, true));
+
+ std::list<std::string> intials = InterpreterImpl::tokenizeIdRefs(ATTR(transition, "target"));
+ for (std::list<std::string>::iterator initIter = intials.begin(); initIter != intials.end(); initIter++) {
+ // the 'target' of a <transition> inside an <initial> or <history> element: all the states must be descendants of the containing <state> or <parallel> element
+ if (!InterpreterImpl::isMember(seenStates[*initIter], childs)) {
+ issues.push_back(InterpreterIssue("Target of initial transition references non-child state '" + *initIter + "'", transition, InterpreterIssue::USCXML_ISSUE_FATAL));
+ }
+ }
+ }
+ }
// check that all invokers exists
@@ -618,22 +620,22 @@ NEXT_TRANSITION:
for (int i = 0; i < allElements.size(); i++) {
Element<std::string> element = Element<std::string>(allElements[i]);
std::string localName = LOCALNAME(element);
-
- if (reqAttr.find(localName) != reqAttr.end()) {
- for (std::set<std::string>::const_iterator reqIter = reqAttr[localName].begin();
- reqIter != reqAttr[localName].end(); reqIter++) {
- if (!HAS_ATTR(element, *reqIter)) {
- issues.push_back(InterpreterIssue("Element " + localName + " is missing required attribute '" + *reqIter + "'", element, InterpreterIssue::USCXML_ISSUE_WARNING));
- }
- if (HAS_ATTR(element, *reqIter) && ATTR(element, *reqIter).size() == 0) {
- issues.push_back(InterpreterIssue("Required attribute '" + *reqIter + "' of element " + localName + " is empty", element, InterpreterIssue::USCXML_ISSUE_WARNING));
- }
- }
- }
-
- if (localName == "scxml") // can be anywhere: <assign>, <content>, <other:embed>
- continue;
-
+
+ if (reqAttr.find(localName) != reqAttr.end()) {
+ for (std::set<std::string>::const_iterator reqIter = reqAttr[localName].begin();
+ reqIter != reqAttr[localName].end(); reqIter++) {
+ if (!HAS_ATTR(element, *reqIter)) {
+ issues.push_back(InterpreterIssue("Element " + localName + " is missing required attribute '" + *reqIter + "'", element, InterpreterIssue::USCXML_ISSUE_WARNING));
+ }
+ if (HAS_ATTR(element, *reqIter) && ATTR(element, *reqIter).size() == 0) {
+ issues.push_back(InterpreterIssue("Required attribute '" + *reqIter + "' of element " + localName + " is empty", element, InterpreterIssue::USCXML_ISSUE_WARNING));
+ }
+ }
+ }
+
+ if (localName == "scxml") // can be anywhere: <assign>, <content>, <other:embed>
+ continue;
+
if (!element.getParentNode() || element.getParentNode().getNodeType() != Node_base::ELEMENT_NODE) {
issues.push_back(InterpreterIssue("Parent of " + localName + " is no element", element, InterpreterIssue::USCXML_ISSUE_WARNING));
continue;
@@ -649,123 +651,123 @@ NEXT_TRANSITION:
}
}
- // check attribute constraints
- {
- for (int i = 0; i < initials.size(); i++) {
- Element<std::string> initial = Element<std::string>(initials[i]);
- if (initial.getParentNode() && initial.getParentNode().getNodeType() == Node_base::ELEMENT_NODE) {
- Element<std::string> state(initial.getParentNode());
- if (HAS_ATTR(state, "initial")) {
- issues.push_back(InterpreterIssue("State with initial attribute cannot have <initial> child ", state, InterpreterIssue::USCXML_ISSUE_WARNING));
- }
- if (InterpreterImpl::isAtomic(state)) {
- issues.push_back(InterpreterIssue("Atomic state cannot have <initial> child ", state, InterpreterIssue::USCXML_ISSUE_WARNING));
- }
- }
- }
- for (int i = 0; i < allStates.size(); i++) {
- Element<std::string> state = Element<std::string>(allStates[i]);
- if (InterpreterImpl::isAtomic(state) && HAS_ATTR(state, "initial")) {
- issues.push_back(InterpreterIssue("Atomic state cannot have initial attribute ", state, InterpreterIssue::USCXML_ISSUE_WARNING));
- }
- }
-
- for (int i = 0; i < assigns.size(); i++) {
- Element<std::string> assign = Element<std::string>(assigns[i]);
- if (HAS_ATTR(assign, "expr") && assign.getChildNodes().getLength() > 0) {
- issues.push_back(InterpreterIssue("Assign element cannot have expr attribute and children", assign, InterpreterIssue::USCXML_ISSUE_WARNING));
- }
- }
-
- for (int i = 0; i < contents.size(); i++) {
- Element<std::string> content = Element<std::string>(contents[i]);
- if (HAS_ATTR(content, "expr") && content.getChildNodes().getLength() > 0) {
- issues.push_back(InterpreterIssue("Content element cannot have expr attribute and children", content, InterpreterIssue::USCXML_ISSUE_WARNING));
- }
- }
-
- for (int i = 0; i < params.size(); i++) {
- Element<std::string> param = Element<std::string>(params[i]);
- if (HAS_ATTR(param, "expr") && HAS_ATTR(param, "location")) {
- issues.push_back(InterpreterIssue("Param element cannot have both expr and location attribute", param, InterpreterIssue::USCXML_ISSUE_WARNING));
- }
- }
-
- for (int i = 0; i < scripts.size(); i++) {
- Element<std::string> script = Element<std::string>(scripts[i]);
- if (HAS_ATTR(script, "src") && script.getChildNodes().getLength() > 0) {
- issues.push_back(InterpreterIssue("Script element cannot have src attribute and children", script, InterpreterIssue::USCXML_ISSUE_WARNING));
- }
- }
-
- for (int i = 0; i < sends.size(); i++) {
- Element<std::string> send = Element<std::string>(sends[i]);
- if (HAS_ATTR(send, "event") && HAS_ATTR(send, "eventexpr")) {
- issues.push_back(InterpreterIssue("Send element cannot have both event and eventexpr attribute", send, InterpreterIssue::USCXML_ISSUE_WARNING));
- }
- if (HAS_ATTR(send, "target") && HAS_ATTR(send, "targetexpr")) {
- issues.push_back(InterpreterIssue("Send element cannot have both target and targetexpr attribute", send, InterpreterIssue::USCXML_ISSUE_WARNING));
- }
- if (HAS_ATTR(send, "type") && HAS_ATTR(send, "typeexpr")) {
- issues.push_back(InterpreterIssue("Send element cannot have both type and typeexpr attribute", send, InterpreterIssue::USCXML_ISSUE_WARNING));
- }
- if (HAS_ATTR(send, "id") && HAS_ATTR(send, "idlocation")) {
- issues.push_back(InterpreterIssue("Send element cannot have both id and idlocation attribute", send, InterpreterIssue::USCXML_ISSUE_WARNING));
- }
- if (HAS_ATTR(send, "delay") && HAS_ATTR(send, "delayexpr")) {
- issues.push_back(InterpreterIssue("Send element cannot have both delay and delayexpr attribute", send, InterpreterIssue::USCXML_ISSUE_WARNING));
- }
- if (HAS_ATTR(send, "delay") && HAS_ATTR(send, "target") && ATTR(send, "target")== "_internal") {
- issues.push_back(InterpreterIssue("Send element cannot have delay with target _internal", send, InterpreterIssue::USCXML_ISSUE_WARNING));
- }
-
- NodeSet<std::string> contentChilds = InterpreterImpl::filterChildElements(_nsInfo.xmlNSPrefix + "content", send, false);
- NodeSet<std::string> paramChilds = InterpreterImpl::filterChildElements(_nsInfo.xmlNSPrefix + "param", send, false);
-
- if (HAS_ATTR(send, "namelist") && contentChilds.size() > 0) {
- issues.push_back(InterpreterIssue("Send element cannot have namelist attribute and content child", send, InterpreterIssue::USCXML_ISSUE_WARNING));
- }
-
- if (paramChilds.size() > 0 && contentChilds.size() > 0) {
- issues.push_back(InterpreterIssue("Send element cannot have param child and content child", send, InterpreterIssue::USCXML_ISSUE_WARNING));
- }
-
- }
- for (int i = 0; i < cancels.size(); i++) {
- Element<std::string> cancel = Element<std::string>(cancels[i]);
- if (HAS_ATTR(cancel, "sendid") && HAS_ATTR(cancel, "sendidexpr")) {
- issues.push_back(InterpreterIssue("Cancel element cannot have both sendid and eventexpr sendidexpr", cancel, InterpreterIssue::USCXML_ISSUE_WARNING));
- }
- }
-
- for (int i = 0; i < invokes.size(); i++) {
- Element<std::string> invoke = Element<std::string>(invokes[i]);
- if (HAS_ATTR(invoke, "type") && HAS_ATTR(invoke, "typeexpr")) {
- issues.push_back(InterpreterIssue("Invoke element cannot have both type and typeexpr attribute", invoke, InterpreterIssue::USCXML_ISSUE_WARNING));
- }
- if (HAS_ATTR(invoke, "src") && HAS_ATTR(invoke, "srcexpr")) {
- issues.push_back(InterpreterIssue("Invoke element cannot have both src and srcexpr attribute", invoke, InterpreterIssue::USCXML_ISSUE_WARNING));
- }
- if (HAS_ATTR(invoke, "id") && HAS_ATTR(invoke, "idlocation")) {
- issues.push_back(InterpreterIssue("Invoke element cannot have both id and idlocation attribute", invoke, InterpreterIssue::USCXML_ISSUE_WARNING));
- }
- if (HAS_ATTR(invoke, "namelist") && InterpreterImpl::filterChildElements(_nsInfo.xmlNSPrefix + "param", invoke, false).size() > 0) {
- issues.push_back(InterpreterIssue("Invoke element cannot have namelist attribute and param child", invoke, InterpreterIssue::USCXML_ISSUE_WARNING));
- }
- if (HAS_ATTR(invoke, "src") && InterpreterImpl::filterChildElements(_nsInfo.xmlNSPrefix + "content", invoke, false).size() > 0) {
- issues.push_back(InterpreterIssue("Invoke element cannot have src attribute and content child", invoke, InterpreterIssue::USCXML_ISSUE_WARNING));
-
- }
- }
- for (int i = 0; i < doneDatas.size(); i++) {
- Element<std::string> donedata = Element<std::string>(doneDatas[i]);
- if (InterpreterImpl::filterChildElements(_nsInfo.xmlNSPrefix + "content", donedata, false).size() > 0 &&
- InterpreterImpl::filterChildElements(_nsInfo.xmlNSPrefix + "param", donedata, false).size() > 0) {
- issues.push_back(InterpreterIssue("Donedata element cannot have param child and content child", donedata, InterpreterIssue::USCXML_ISSUE_WARNING));
-
- }
- }
- }
+ // check attribute constraints
+ {
+ for (int i = 0; i < initials.size(); i++) {
+ Element<std::string> initial = Element<std::string>(initials[i]);
+ if (initial.getParentNode() && initial.getParentNode().getNodeType() == Node_base::ELEMENT_NODE) {
+ Element<std::string> state(initial.getParentNode());
+ if (HAS_ATTR(state, "initial")) {
+ issues.push_back(InterpreterIssue("State with initial attribute cannot have <initial> child ", state, InterpreterIssue::USCXML_ISSUE_WARNING));
+ }
+ if (InterpreterImpl::isAtomic(state)) {
+ issues.push_back(InterpreterIssue("Atomic state cannot have <initial> child ", state, InterpreterIssue::USCXML_ISSUE_WARNING));
+ }
+ }
+ }
+ for (int i = 0; i < allStates.size(); i++) {
+ Element<std::string> state = Element<std::string>(allStates[i]);
+ if (InterpreterImpl::isAtomic(state) && HAS_ATTR(state, "initial")) {
+ issues.push_back(InterpreterIssue("Atomic state cannot have initial attribute ", state, InterpreterIssue::USCXML_ISSUE_WARNING));
+ }
+ }
+
+ for (int i = 0; i < assigns.size(); i++) {
+ Element<std::string> assign = Element<std::string>(assigns[i]);
+ if (HAS_ATTR(assign, "expr") && assign.getChildNodes().getLength() > 0) {
+ issues.push_back(InterpreterIssue("Assign element cannot have expr attribute and children", assign, InterpreterIssue::USCXML_ISSUE_WARNING));
+ }
+ }
+
+ for (int i = 0; i < contents.size(); i++) {
+ Element<std::string> content = Element<std::string>(contents[i]);
+ if (HAS_ATTR(content, "expr") && content.getChildNodes().getLength() > 0) {
+ issues.push_back(InterpreterIssue("Content element cannot have expr attribute and children", content, InterpreterIssue::USCXML_ISSUE_WARNING));
+ }
+ }
+
+ for (int i = 0; i < params.size(); i++) {
+ Element<std::string> param = Element<std::string>(params[i]);
+ if (HAS_ATTR(param, "expr") && HAS_ATTR(param, "location")) {
+ issues.push_back(InterpreterIssue("Param element cannot have both expr and location attribute", param, InterpreterIssue::USCXML_ISSUE_WARNING));
+ }
+ }
+
+ for (int i = 0; i < scripts.size(); i++) {
+ Element<std::string> script = Element<std::string>(scripts[i]);
+ if (HAS_ATTR(script, "src") && script.getChildNodes().getLength() > 0) {
+ issues.push_back(InterpreterIssue("Script element cannot have src attribute and children", script, InterpreterIssue::USCXML_ISSUE_WARNING));
+ }
+ }
+
+ for (int i = 0; i < sends.size(); i++) {
+ Element<std::string> send = Element<std::string>(sends[i]);
+ if (HAS_ATTR(send, "event") && HAS_ATTR(send, "eventexpr")) {
+ issues.push_back(InterpreterIssue("Send element cannot have both event and eventexpr attribute", send, InterpreterIssue::USCXML_ISSUE_WARNING));
+ }
+ if (HAS_ATTR(send, "target") && HAS_ATTR(send, "targetexpr")) {
+ issues.push_back(InterpreterIssue("Send element cannot have both target and targetexpr attribute", send, InterpreterIssue::USCXML_ISSUE_WARNING));
+ }
+ if (HAS_ATTR(send, "type") && HAS_ATTR(send, "typeexpr")) {
+ issues.push_back(InterpreterIssue("Send element cannot have both type and typeexpr attribute", send, InterpreterIssue::USCXML_ISSUE_WARNING));
+ }
+ if (HAS_ATTR(send, "id") && HAS_ATTR(send, "idlocation")) {
+ issues.push_back(InterpreterIssue("Send element cannot have both id and idlocation attribute", send, InterpreterIssue::USCXML_ISSUE_WARNING));
+ }
+ if (HAS_ATTR(send, "delay") && HAS_ATTR(send, "delayexpr")) {
+ issues.push_back(InterpreterIssue("Send element cannot have both delay and delayexpr attribute", send, InterpreterIssue::USCXML_ISSUE_WARNING));
+ }
+ if (HAS_ATTR(send, "delay") && HAS_ATTR(send, "target") && ATTR(send, "target")== "_internal") {
+ issues.push_back(InterpreterIssue("Send element cannot have delay with target _internal", send, InterpreterIssue::USCXML_ISSUE_WARNING));
+ }
+
+ NodeSet<std::string> contentChilds = InterpreterImpl::filterChildElements(_nsInfo.xmlNSPrefix + "content", send, false);
+ NodeSet<std::string> paramChilds = InterpreterImpl::filterChildElements(_nsInfo.xmlNSPrefix + "param", send, false);
+
+ if (HAS_ATTR(send, "namelist") && contentChilds.size() > 0) {
+ issues.push_back(InterpreterIssue("Send element cannot have namelist attribute and content child", send, InterpreterIssue::USCXML_ISSUE_WARNING));
+ }
+
+ if (paramChilds.size() > 0 && contentChilds.size() > 0) {
+ issues.push_back(InterpreterIssue("Send element cannot have param child and content child", send, InterpreterIssue::USCXML_ISSUE_WARNING));
+ }
+
+ }
+ for (int i = 0; i < cancels.size(); i++) {
+ Element<std::string> cancel = Element<std::string>(cancels[i]);
+ if (HAS_ATTR(cancel, "sendid") && HAS_ATTR(cancel, "sendidexpr")) {
+ issues.push_back(InterpreterIssue("Cancel element cannot have both sendid and eventexpr sendidexpr", cancel, InterpreterIssue::USCXML_ISSUE_WARNING));
+ }
+ }
+
+ for (int i = 0; i < invokes.size(); i++) {
+ Element<std::string> invoke = Element<std::string>(invokes[i]);
+ if (HAS_ATTR(invoke, "type") && HAS_ATTR(invoke, "typeexpr")) {
+ issues.push_back(InterpreterIssue("Invoke element cannot have both type and typeexpr attribute", invoke, InterpreterIssue::USCXML_ISSUE_WARNING));
+ }
+ if (HAS_ATTR(invoke, "src") && HAS_ATTR(invoke, "srcexpr")) {
+ issues.push_back(InterpreterIssue("Invoke element cannot have both src and srcexpr attribute", invoke, InterpreterIssue::USCXML_ISSUE_WARNING));
+ }
+ if (HAS_ATTR(invoke, "id") && HAS_ATTR(invoke, "idlocation")) {
+ issues.push_back(InterpreterIssue("Invoke element cannot have both id and idlocation attribute", invoke, InterpreterIssue::USCXML_ISSUE_WARNING));
+ }
+ if (HAS_ATTR(invoke, "namelist") && InterpreterImpl::filterChildElements(_nsInfo.xmlNSPrefix + "param", invoke, false).size() > 0) {
+ issues.push_back(InterpreterIssue("Invoke element cannot have namelist attribute and param child", invoke, InterpreterIssue::USCXML_ISSUE_WARNING));
+ }
+ if (HAS_ATTR(invoke, "src") && InterpreterImpl::filterChildElements(_nsInfo.xmlNSPrefix + "content", invoke, false).size() > 0) {
+ issues.push_back(InterpreterIssue("Invoke element cannot have src attribute and content child", invoke, InterpreterIssue::USCXML_ISSUE_WARNING));
+
+ }
+ }
+ for (int i = 0; i < doneDatas.size(); i++) {
+ Element<std::string> donedata = Element<std::string>(doneDatas[i]);
+ if (InterpreterImpl::filterChildElements(_nsInfo.xmlNSPrefix + "content", donedata, false).size() > 0 &&
+ InterpreterImpl::filterChildElements(_nsInfo.xmlNSPrefix + "param", donedata, false).size() > 0) {
+ issues.push_back(InterpreterIssue("Donedata element cannot have param child and content child", donedata, InterpreterIssue::USCXML_ISSUE_WARNING));
+
+ }
+ }
+ }
// check that the datamodel is known if not already instantiated
if (!interpreter->_dataModel) {
diff --git a/src/uscxml/debug/InterpreterIssue.h b/src/uscxml/debug/InterpreterIssue.h
index 0e1f949..5959d07 100644
--- a/src/uscxml/debug/InterpreterIssue.h
+++ b/src/uscxml/debug/InterpreterIssue.h
@@ -36,13 +36,13 @@ public:
USCXML_ISSUE_INFO
};
- InterpreterIssue(const std::string& msg, Arabica::DOM::Node<std::string> node, IssueSeverity severity, const std::string& specRef = "");
+ InterpreterIssue(const std::string& msg, Arabica::DOM::Node<std::string> node, IssueSeverity severity, const std::string& specRef = "");
std::string xPath;
- std::string message;
+ std::string message;
Arabica::DOM::Node<std::string> node;
IssueSeverity severity;
- std::string specRef;
+ std::string specRef;
private:
static std::list<InterpreterIssue> forInterpreter(InterpreterImpl* interpreter);