void XPathDataModel::assign(const XPathValue<std::string>& key, const XPathValue<std::string>& value, const Element<std::string>& assignElem) { switch (key.type()) { case NODE_SET: if (key.asNodeSet().size() == 0) { ERROR_EXECUTION_THROW("key for assign is empty nodeset"); } switch (value.type()) { case STRING: assign(key.asNodeSet(), value.asString(), assignElem); break; case Arabica::XPath::BOOL: assign(key.asNodeSet(), value.asBool(), assignElem); break; case NUMBER: assign(key.asNodeSet(), value.asNumber(), assignElem); break; case NODE_SET: assign(key.asNodeSet(), value.asNodeSet(), assignElem); break; case ANY: ERROR_EXECUTION_THROW("Type ANY as key for assign not supported"); } break; case STRING: case Arabica::XPath::BOOL: case NUMBER: case ANY: ERROR_EXECUTION_THROW("Type ANY as key for assign not supported") break; } }
int PromelaDataModel::dataToInt(const Data& data) { if (data.type != Data::INTERPRETED) ERROR_EXECUTION_THROW("Operand is not integer"); int value = strTo<int>(data.atom); if (data.atom.compare(toStr(value)) != 0) ERROR_EXECUTION_THROW("Operand is not integer"); return value; }
uint32_t PromelaDataModel::getLength(const std::string& expr) { if (!isDeclared(expr)) { ERROR_EXECUTION_THROW("Variable '" + expr + "' was not declared"); } if (!_variables[expr].hasKey("size")) { ERROR_EXECUTION_THROW("Variable '" + expr + "' is no array"); } return strTo<int>(_variables[expr]["size"].atom); }
bool XPathDataModel::evalAsBool(const Arabica::DOM::Element<std::string>& node, const std::string& expr) { // std::cout << std::endl << evalAsString(expr); XPathValue<std::string> result; try { result = _xpath.evaluate_expr(expr, _doc); } catch(SyntaxException e) { ERROR_EXECUTION_THROW(e.what()); } catch(std::runtime_error e) { ERROR_EXECUTION_THROW(e.what()); } return result.asBool(); }
void PromelaDataModel::assign(const Element<std::string>& assignElem, const Node<std::string>& node, const std::string& content) { std::string expr; std::string key; std::string value; if (node) { ERROR_EXECUTION_THROW("Assigning DOM node to variable is not supported"); } if (HAS_ATTR(assignElem, "id")) { key = ATTR(assignElem, "id"); } else if (HAS_ATTR(assignElem, "location")) { key = ATTR(assignElem, "location"); } if (HAS_ATTR(assignElem, "expr")) { if (key.length() == 0) { ERROR_EXECUTION_THROW("Assign element has neither id nor location"); } value = ATTR(assignElem, "expr"); } else { value = content; } if (key.length() > 0) { PromelaParser parser(key); // declaration is an array? if (parser.ast->operands.size() > 0 && parser.ast->operands.back()->operands.size() > 0 && parser.ast->operands.back()->operands.back()->type == PML_VAR_ARRAY) { evaluateDecl(parser.ast); expr = content; } else if (value.length() > 0) { expr = key + " = " + value + ";"; } else { // declaration expr = key + ";"; } } else { expr = content; } PromelaParser parser(expr, 2, PromelaParser::PROMELA_DECL, PromelaParser::PROMELA_STMNT); if (parser.type == PromelaParser::PROMELA_DECL) evaluateDecl(parser.ast); if (parser.type == PromelaParser::PROMELA_STMNT) evaluateStmnt(parser.ast); // parser.dump(); // std::cout << Data::toJSON(_variables) << std::endl; }
void XPathDataModel::init(const Element<std::string>& dataElem, const Node<std::string>& node, const std::string& content) { std::string location; if (HAS_ATTR(dataElem, "id")) { location = ATTR(dataElem, "id"); } else if (HAS_ATTR(dataElem, "location")) { location = ATTR(dataElem, "location"); } NodeSet<std::string> nodeSet; if (node || (content.length() > 0)) { _datamodel.appendChild(_doc.importNode(dataElem, true)); nodeSet.push_back(dataElem); } else if (HAS_ATTR(dataElem, "expr")) { try { Element<std::string> container = _doc.createElement("data"); container.setAttribute("id", location); XPathValue<std::string> expr = _xpath.evaluate_expr(ATTR(dataElem, "expr"), _doc); switch (expr.type()) { case NODE_SET: { for (size_t i = 0; i < expr.asNodeSet().size(); i++) { container.appendChild(expr.asNodeSet()[i].cloneNode(true)); nodeSet.push_back(expr.asNodeSet()[i].cloneNode(true)); } break; } case STRING: container.appendChild(_doc.createTextNode(expr.asString())); nodeSet.push_back(_doc.createTextNode(expr.asString())); break; case NUMBER: { container.appendChild(_doc.createTextNode(toStr(expr.asNumber()))); nodeSet.push_back(_doc.createTextNode(toStr(expr.asNumber()))); break; } case Arabica::XPath::BOOL: case ANY: ERROR_EXECUTION_THROW("expr evaluates to type ANY"); } _datamodel.appendChild(container); } catch (SyntaxException e) { ERROR_EXECUTION_THROW(e.what()); } } else { LOG(ERROR) << "data element has no content"; } _varResolver.setVariable(location, nodeSet); }
void PromelaDataModel::setVariable(void* ast, Data value) { PromelaParserNode* node = (PromelaParserNode*)ast; std::list<PromelaParserNode*>::iterator opIter = node->operands.begin(); switch (node->type) { case PML_VAR_ARRAY: { PromelaParserNode* name = *opIter++; PromelaParserNode* expr = *opIter++; if (INVALID_ASSIGNMENT(name->value)) { ERROR_EXECUTION_THROW("Cannot assign to " + name->value); } int index = dataToInt(evaluateExpr(expr)); if (_variables.compound.find(name->value) == _variables.compound.end()) { ERROR_EXECUTION_THROW("No variable " + name->value + " was declared"); } if (!_variables[name->value].hasKey("size")) { ERROR_EXECUTION_THROW("Variable " + name->value + " is no array"); } if (strTo<int>(_variables[name->value]["size"].atom) <= index) { ERROR_EXECUTION_THROW("Index " + toStr(index) + " in array " + name->value + "[" + _variables[name->value]["size"].atom + "] is out of bounds"); } _variables.compound[name->value].compound["value"][index] = value; break; } case PML_NAME: if (INVALID_ASSIGNMENT(node->value)) { ERROR_EXECUTION_THROW("Cannot assign to " + node->value); } _variables.compound[node->value].compound["value"] = value; break; default: break; } // std::cout << Data::toJSON(_variables) << std::endl; }
void XPathDataModel::assign(const NodeSet<std::string>& key, const std::string& value, const Element<std::string>& assignElem) { if (key.size() == 0) return; for (size_t i = 0; i < key.size(); i++) { Node<std::string> node = key[i]; switch (node.getNodeType()) { case Node_base::ATTRIBUTE_NODE: { Attr<std::string> attr(node); attr.setValue(value); break; } case Node_base::TEXT_NODE: { Text<std::string> text(node); text.setNodeValue(value); break; } case Node_base::ELEMENT_NODE: { Element<std::string> element(node); if (HAS_ATTR(assignElem, "type") && iequals(ATTR(assignElem, "type"), "addattribute")) { // addattribute: Add an attribute with the name specified by 'attr' // and value specified by 'expr' to the node specified by 'location'. if (!HAS_ATTR(assignElem, "attr")) ERROR_EXECUTION_THROW("Assign element is missing 'attr'"); element.setAttribute(ATTR(assignElem, "attr"), value); } else { /// test 547 while(element.hasChildNodes()) element.removeChild(element.getChildNodes().item(0)); Text<std::string> text = _doc.createTextNode(value); element.appendChild(text); } break; } default: ERROR_EXECUTION_THROW("Unsupported node type with assign"); break; } } }
std::string XPathDataModel::evalAsString(const std::string& expr) { XPathValue<std::string> result; try { result = _xpath.evaluate_expr(expr, _doc); } catch(SyntaxException e) { ERROR_EXECUTION_THROW(e.what()); } catch(std::runtime_error e) { ERROR_EXECUTION_THROW(e.what()); } switch (result.type()) { case STRING: return result.asString(); break; case Arabica::XPath::BOOL: // MSVC croaks with ambiguous symbol without qualified name return (result.asBool() ? "true" : "false"); break; case NUMBER: return toStr(result.asNumber()); break; case NODE_SET: { NodeSet<std::string> nodeSet = result.asNodeSet(); std::stringstream ss; for (size_t i = 0; i < nodeSet.size(); i++) { ss << nodeSet[i]; if (nodeSet[i].getNodeType() != Node_base::TEXT_NODE) { ss << std::endl; } } return ss.str(); break; } case ANY: ERROR_EXECUTION_THROW("Type ANY not supported to evaluate as string"); break; } return "undefined"; }
uint32_t XPathDataModel::getLength(const std::string& expr) { // std::cout << _datamodel << std::endl; XPathValue<std::string> result = _xpath.evaluate_expr(expr, _doc); switch(result.type()) { case NUMBER: return result.asNumber(); break; case NODE_SET: return result.asNodeSet().size(); break; default: ERROR_EXECUTION_THROW("'" + expr + "' does not evaluate to an array."); } return 0; }
XPathValue<std::string> NodeSetVariableResolver::resolveVariable(const std::string& namepaceUri, const std::string& name) const { std::map<std::string, NodeSet<std::string> >::const_iterator n = _variables.find(name); if(n == _variables.end()) { ERROR_EXECUTION_THROW("No variable named '" + name + "'"); } #if VERBOSE std::cout << std::endl << "Getting " << name << ":" << std::endl; for (size_t i = 0; i < n->second.size(); i++) { std::cout << n->second[i].getNodeType() << " | " << n->second[i] << std::endl; } std::cout << std::endl; #endif return XPathValue<std::string>(new NodeSetValue<std::string>(n->second)); }
boost::shared_ptr<ExecutableContentImpl> Factory::createExecutableContent(const std::string& localName, const std::string& nameSpace, InterpreterImpl* interpreter) { // do we have this type in this factory? std::string actualNameSpace = (nameSpace.length() == 0 ? "http://www.w3.org/2005/07/scxml" : nameSpace); if (_executableContent.find(std::make_pair(localName, actualNameSpace)) != _executableContent.end()) { boost::shared_ptr<ExecutableContentImpl> execContent = _executableContent[std::make_pair(localName, actualNameSpace)]->create(interpreter); execContent->setInterpreter(interpreter); return execContent; } // lookup in parent factory if (_parentFactory) { return _parentFactory->createExecutableContent(localName, nameSpace, interpreter); } else { ERROR_EXECUTION_THROW("No Executable content name '" + localName + "' in namespace '" + actualNameSpace + "' known"); } return boost::shared_ptr<ExecutableContentImpl>(); }
void XPathDataModel::assign(const NodeSet<std::string>& key, const NodeSet<std::string>& value, const Element<std::string>& assignElem) { if (key.size() == 0) return; if (value.size() == 0 || !value[0]) return; for (size_t i = 0; i < key.size(); i++) { switch (key[i].getNodeType()) case Node_base::ELEMENT_NODE: { assign(Element<std::string>(key[i]), value, assignElem); break; default: // std::cout << key[i].getNodeType() << std::endl; ERROR_EXECUTION_THROW("Unsupported node type for assign"); break; } } }
void PromelaDataModel::evaluateStmnt(void* ast) { PromelaParserNode* node = (PromelaParserNode*)ast; std::list<PromelaParserNode*>::iterator opIter = node->operands.begin(); switch (node->type) { case PML_ASGN: { PromelaParserNode* name = *opIter++; PromelaParserNode* expr = *opIter++; setVariable(name, evaluateExpr(expr)); break; } case PML_STMNT: { while(opIter != node->operands.end()) { evaluateStmnt(*opIter++); } break; } default: ERROR_EXECUTION_THROW("No support for " + PromelaParserNode::typeToDesc(node->type) + " statement implemented"); } }
boost::shared_ptr<IOProcessorImpl> Factory::createIOProcessor(const std::string& type, InterpreterImpl* interpreter) { // do we have this type ourself? if (_ioProcessorAliases.find(type) != _ioProcessorAliases.end()) { std::string canonicalName = _ioProcessorAliases[type]; if (_ioProcessors.find(canonicalName) != _ioProcessors.end()) { boost::shared_ptr<IOProcessorImpl> ioProc = _ioProcessors[canonicalName]->create(interpreter); ioProc->setInterpreter(interpreter); return ioProc; } } // lookup in parent factory if (_parentFactory) { return _parentFactory->createIOProcessor(type, interpreter); } else { ERROR_EXECUTION_THROW("No IOProcessor named '" + type + "' known"); } return boost::shared_ptr<IOProcessorImpl>(); }
boost::shared_ptr<DataModelImpl> Factory::createDataModel(const std::string& type, InterpreterImpl* interpreter) { // do we have this type ourself? if (_dataModelAliases.find(type) != _dataModelAliases.end()) { std::string canonicalName = _dataModelAliases[type]; if (_dataModels.find(canonicalName) != _dataModels.end()) { boost::shared_ptr<DataModelImpl> dataModel = _dataModels[canonicalName]->create(interpreter); dataModel->setInterpreter(interpreter); return dataModel; } } // lookup in parent factory if (_parentFactory) { return _parentFactory->createDataModel(type, interpreter); } else { ERROR_EXECUTION_THROW("No Datamodel name '" + type + "' known"); } return boost::shared_ptr<DataModelImpl>(); }
void PromelaDataModel::setForeach(const std::string& item, const std::string& array, const std::string& index, uint32_t iteration) { // assign array element to item std::stringstream ss; ss << array << "[" << iteration << "]"; PromelaParser itemParser(item, 1, PromelaParser::PROMELA_EXPR); if (itemParser.ast->type != PML_NAME) ERROR_EXECUTION_THROW("Expression '" + item + "' is no valid item"); PromelaParser arrayParser(ss.str(), 1, PromelaParser::PROMELA_EXPR); setVariable(itemParser.ast, getVariable(arrayParser.ast)); if (index.length() > 0) { PromelaParser indexParser(index, 1, PromelaParser::PROMELA_EXPR); setVariable(indexParser.ast, iteration); } }
void DataModelImpl::addExtension(DataModelExtension* ext) { ERROR_EXECUTION_THROW("DataModel does not support extensions"); }
void XPathDataModel::assign(const Element<std::string>& key, const NodeSet<std::string>& value, const Element<std::string>& assignElem) { Element<std::string> element(key); if (value.size() == 0 || !value[0]) return; if (false) { } else if (assignElem && HAS_ATTR(assignElem, "type") && iequals(ATTR(assignElem, "type"), "firstchild")) { // firstchild: Insert the value specified by 'expr' before all of the children at 'location'. for (size_t i = value.size(); i; i--) { Node<std::string> importedNode = (value[i-1].getOwnerDocument() == _doc ? value[i-1].cloneNode(true) : _doc.importNode(value[i-1], true)); element.insertBefore(importedNode, element.getFirstChild()); } } else if (assignElem && HAS_ATTR(assignElem, "type") && iequals(ATTR(assignElem, "type"), "lastchild")) { // lastchild: Insert the value specified by 'expr' after all of the children at 'location'. for (size_t i = 0; i < value.size(); i++) { Node<std::string> importedNode = (value[i].getOwnerDocument() == _doc ? value[i].cloneNode(true) : _doc.importNode(value[i], true)); element.appendChild(importedNode); } } else if (assignElem && HAS_ATTR(assignElem, "type") && iequals(ATTR(assignElem, "type"), "previoussibling")) { // previoussibling: Insert the value specified by 'expr' before the // node specified by 'location', keeping the same parent. Node<std::string> parent = element.getParentNode(); if (!parent) ERROR_EXECUTION_THROW("Node has no parent"); for (size_t i = 0; i < value.size(); i++) { Node<std::string> importedNode = (value[i].getOwnerDocument() == _doc ? value[i].cloneNode(true) : _doc.importNode(value[i], true)); parent.insertBefore(importedNode, element); } } else if (assignElem && HAS_ATTR(assignElem, "type") && iequals(ATTR(assignElem, "type"), "nextsibling")) { // nextsibling: Insert the value specified by 'expr' after the node // specified by 'location', keeping the same parent. Node<std::string> parent = element.getParentNode(); if (!parent) ERROR_EXECUTION_THROW("Node has no parent"); for (size_t i = value.size(); i; i--) { Node<std::string> importedNode = (value[i-1].getOwnerDocument() == _doc ? value[i-1].cloneNode(true) : _doc.importNode(value[i-1], true)); Node<std::string> nextSibling = element.getNextSibling(); if (nextSibling) { parent.insertBefore(importedNode, element.getNextSibling()); } else { parent.appendChild(importedNode); } } } else if (assignElem && HAS_ATTR(assignElem, "type") && iequals(ATTR(assignElem, "type"), "replace")) { // replace: Replace the node specified by 'location' by the value specified by 'expr'. Node<std::string> parent = element.getParentNode(); if (!parent) ERROR_EXECUTION_THROW("Node has no parent"); if (value.size() != 1) ERROR_EXECUTION_THROW("Value not singular"); Node<std::string> importedNode = (value[0].getOwnerDocument() == _doc ? value[0].cloneNode(true) : _doc.importNode(value[0], true)); parent.replaceChild(importedNode, element); } else if (assignElem && HAS_ATTR(assignElem, "type") && iequals(ATTR(assignElem, "type"), "delete")) { // delete: Delete the node specified by 'location'. ('expr' is ignored.). Node<std::string> parent = element.getParentNode(); if (!parent) ERROR_EXECUTION_THROW("Node has no parent"); parent.removeChild(element); } else { // replacechildren: Replace all the children at 'location' with the value specified by 'expr'. while(element.hasChildNodes()) element.removeChild(element.getChildNodes().item(0)); for (size_t i = 0; i < value.size(); i++) { Node<std::string> importedNode = element.getOwnerDocument().importNode(value[i], true); element.appendChild(importedNode); } } }
void PromelaDataModel::evaluateDecl(void* ast) { PromelaParserNode* node = (PromelaParserNode*)ast; if (false) { } else if (node->type == PML_DECL) { std::list<PromelaParserNode*>::iterator opIter = node->operands.begin(); PromelaParserNode* vis = *opIter++; PromelaParserNode* type = *opIter++; PromelaParserNode* varlist = *opIter++; for (std::list<PromelaParserNode*>::iterator nameIter = varlist->operands.begin(); nameIter != varlist->operands.end(); nameIter++) { Data variable; variable.compound["vis"] = Data(vis->value, Data::VERBATIM); variable.compound["type"] = Data(type->value, Data::VERBATIM); if (false) { } else if ((*nameIter)->type == PML_NAME) { // plain variables without initial assignment if (type->value == "mtype") { variable.compound["value"] = Data(_lastMType++, Data::INTERPRETED); } else { variable.compound["value"] = Data(0, Data::INTERPRETED); } _variables.compound[(*nameIter)->value] = variable; } else if ((*nameIter)->type == PML_ASGN) { // initially assigned variables std::list<PromelaParserNode*>::iterator opIterAsgn = (*nameIter)->operands.begin(); PromelaParserNode* name = *opIterAsgn++; PromelaParserNode* expr = *opIterAsgn++; variable.compound["value"] = evaluateExpr(expr); assert(opIterAsgn == (*nameIter)->operands.end()); _variables.compound[name->value] = variable; } else if ((*nameIter)->type == PML_VAR_ARRAY) { // variable arrays std::list<PromelaParserNode*>::iterator opIterAsgn = (*nameIter)->operands.begin(); PromelaParserNode* name = *opIterAsgn++; int size = dataToInt(evaluateExpr(*opIterAsgn++)); variable.compound["size"] = size; for (int i = 0; i < size; i++) { variable.compound["value"].array.push_back(Data(0, Data::INTERPRETED)); } assert(opIterAsgn == (*nameIter)->operands.end()); _variables.compound[name->value] = variable; } else { ERROR_EXECUTION_THROW("Declaring variables via " + PromelaParserNode::typeToDesc((*nameIter)->type) + " not implemented"); } } assert(opIter == node->operands.end()); } else if (node->type == PML_DECLLIST) { for (std::list<PromelaParserNode*>::iterator declIter = node->operands.begin(); declIter != node->operands.end(); declIter++) { evaluateDecl(*declIter); } } else { ERROR_EXECUTION_THROW("Declaring variables via " + PromelaParserNode::typeToDesc(node->type) + " not implemented"); } }
Data PromelaDataModel::evaluateExpr(void* ast) { PromelaParserNode* node = (PromelaParserNode*)ast; std::list<PromelaParserNode*>::iterator opIter = node->operands.begin(); switch (node->type) { case PML_CONST: if (iequals(node->value, "false")) return Data(false); if (iequals(node->value, "true")) return Data(true); return strTo<int>(node->value); case PML_NAME: case PML_VAR_ARRAY: case PML_CMPND: return getVariable(node); case PML_STRING: { std::string stripped = node->value.substr(1, node->value.size() - 2); return Data(stripped, Data::VERBATIM); } case PML_PLUS: return dataToInt(evaluateExpr(*opIter++)) + dataToInt(evaluateExpr(*opIter++)); case PML_MINUS: return dataToInt(evaluateExpr(*opIter++)) - dataToInt(evaluateExpr(*opIter++)); case PML_DIVIDE: return dataToInt(evaluateExpr(*opIter++)) / dataToInt(evaluateExpr(*opIter++)); case PML_MODULO: return dataToInt(evaluateExpr(*opIter++)) % dataToInt(evaluateExpr(*opIter++)); case PML_EQ: { PromelaParserNode* lhs = *opIter++; PromelaParserNode* rhs = *opIter++; Data left = evaluateExpr(lhs); Data right = evaluateExpr(rhs); if (left == right) // overloaded operator== return Data(true); // literal strings or strings in variables if ((lhs->type == PML_STRING || rhs->type == PML_STRING) || (left.type == Data::VERBATIM && right.type == Data::VERBATIM)) { return (left.atom.compare(right.atom) == 0 ? Data(true) : Data(false)); } return dataToInt(left) == dataToInt(right); } case PML_NEG: return !dataToBool(evaluateExpr(*opIter++)); case PML_LT: return dataToInt(evaluateExpr(*opIter++)) < dataToInt(evaluateExpr(*opIter++)); case PML_LE: return dataToInt(evaluateExpr(*opIter++)) <= dataToInt(evaluateExpr(*opIter++)); case PML_GT: return dataToInt(evaluateExpr(*opIter++)) > dataToInt(evaluateExpr(*opIter++)); case PML_GE: return dataToInt(evaluateExpr(*opIter++)) >= dataToInt(evaluateExpr(*opIter++)); case PML_TIMES: return dataToInt(evaluateExpr(*opIter++)) * dataToInt(evaluateExpr(*opIter++)); case PML_LSHIFT: return dataToInt(evaluateExpr(*opIter++)) << dataToInt(evaluateExpr(*opIter++)); case PML_RSHIFT: return dataToInt(evaluateExpr(*opIter++)) >> dataToInt(evaluateExpr(*opIter++)); case PML_AND: case PML_OR: { PromelaParserNode* lhs = *opIter++; PromelaParserNode* rhs = *opIter++; std::cout << "-----" << std::endl; lhs->dump(); rhs->dump(); Data left = evaluateExpr(lhs); Data right = evaluateExpr(rhs); bool truthLeft = dataToBool(left); bool truthRight = dataToBool(right); if (node->type == PML_AND) { return truthLeft && truthRight; } else { return truthLeft || truthRight; } } default: ERROR_EXECUTION_THROW("Support for " + PromelaParserNode::typeToDesc(node->type) + " expressions not implemented"); } return 0; }
void XPathDataModel::assign(const Element<std::string>& assignElem, const Node<std::string>& node, const std::string& content) { std::string location; if (HAS_ATTR(assignElem, "id")) { location = ATTR(assignElem, "id"); } else if (HAS_ATTR(assignElem, "location")) { location = ATTR(assignElem, "location"); } // test 326ff XPathValue<std::string> key = _xpath.evaluate_expr(location, _doc); #ifdef VERBOSE LOG(INFO) << "Key XPath : " << key.asString(); #endif #if 0 if (key.type() == NODE_SET) { try { for (size_t i = 0; i < key.asNodeSet().size(); i++) { Node<std::string> node = key.asNodeSet()[i]; if (node == _varResolver.resolveVariable("", "_ioprocessors").asNodeSet()[0]) ERROR_EXECUTION_THROW("Cannot assign _ioProcessors"); if (node == _varResolver.resolveVariable("", "_sessionid").asNodeSet()[0]) ERROR_EXECUTION_THROW("Cannot assign _sessionid"); if (node == _varResolver.resolveVariable("", "_name").asNodeSet()[0]) ERROR_EXECUTION_THROW("Cannot assign _name"); if (node == _varResolver.resolveVariable("", "_event").asNodeSet()[0]) ERROR_EXECUTION_THROW("Cannot assign _event"); } } catch (Event e) {} } #endif NodeSet<std::string> nodeSet; if (node) { Node<std::string> data = node; while (data) { // do not add empty text as a node if (data.getNodeType() == Node_base::TEXT_NODE) { std::string trimmed = data.getNodeValue(); boost::trim(trimmed); if (trimmed.length() == 0) { data = data.getNextSibling(); continue; } } nodeSet.push_back(data); data = data.getNextSibling(); } assign(key, nodeSet, assignElem); } else if (content.length() > 0) { Text<std::string> textNode = _doc.createTextNode(spaceNormalize(content)); nodeSet.push_back(textNode); assign(key, nodeSet, assignElem); } else if (HAS_ATTR(assignElem, "expr")) { XPathValue<std::string> value = _xpath.evaluate_expr(ATTR(assignElem, "expr"), _doc); #ifdef VERBOSE LOG(INFO) << "Value XPath : " << value.asString(); #endif assign(key, value, assignElem); } else { LOG(ERROR) << "assign element has no content"; } // std::cout << _datamodel << std::endl; }
Data PromelaDataModel::getVariable(void* ast) { PromelaParserNode* node = (PromelaParserNode*)ast; // node->dump(); std::list<PromelaParserNode*>::iterator opIter = node->operands.begin(); switch(node->type) { case PML_NAME: if (_variables.compound.find(node->value) == _variables.compound.end()) { ERROR_EXECUTION_THROW("No variable " + node->value + " was declared"); } // if (_variables[node->value].compound.find("size") != _variables[node->value].compound.end()) { // ERROR_EXECUTION_THROW("Type error: Variable " + node->value + " is an array"); // } return _variables[node->value]["value"]; case PML_VAR_ARRAY: { PromelaParserNode* name = *opIter++; PromelaParserNode* expr = *opIter++; int index = dataToInt(evaluateExpr(expr)); if (_variables.compound.find(name->value) == _variables.compound.end()) { ERROR_EXECUTION_THROW("No variable " + name->value + " was declared"); } if (!_variables[name->value].hasKey("size")) { ERROR_EXECUTION_THROW("Variable " + name->value + " is no array"); } if (strTo<int>(_variables[name->value]["size"].atom) <= index) { ERROR_EXECUTION_THROW("Index " + toStr(index) + " in array " + name->value + "[" + _variables[name->value]["size"].atom + "] is out of bounds"); } return _variables.compound[name->value].compound["value"][index]; } case PML_CMPND: { // node->dump(); // std::cout << Data::toJSON(_variables["_event"]); std::stringstream idPath; PromelaParserNode* name = *opIter++; // special case for _x variables if (name->value.compare("_x") == 0) { PromelaParserNode* what = *opIter++; if (what->type == PML_VAR_ARRAY) { if (what->operands.size() == 2) { std::string arrName = what->operands.front()->value; std::string index = what->operands.back()->value; if (what->operands.back()->type == PML_STRING) { index = index.substr(1, index.size() - 2); // remove quotes } if (arrName.compare("states") == 0) { return Data(_interpreter->isInState(index)); } } } ERROR_EXECUTION_THROW("No variable " + name->value + " was declared"); } if (_variables.compound.find(name->value) == _variables.compound.end()) { ERROR_EXECUTION_THROW("No variable " + name->value + " was declared"); } Data currData = _variables.compound[name->value]["value"]; idPath << name->value; while(opIter != node->operands.end()) { std::string key = (*opIter)->value; idPath << "." << key; if (currData.compound.find(key) == currData.compound.end()) { ERROR_EXECUTION_THROW("No variable " + idPath.str() + " was declared"); } Data tmp = currData.compound[key]; currData = tmp; opIter++; } return currData; } default: ERROR_EXECUTION_THROW("Retrieving value of " + PromelaParserNode::typeToDesc(node->type) + " variable not implemented"); } return 0; }
bool SCXMLIOProcessor::isValidTarget(const std::string& target) { if (target.size() > 0 && (target[0] != '#' || target[1] != '_')) { ERROR_EXECUTION_THROW("Target '" + target + "' not supported in send"); } return true; }
void XPathDataModel::setForeach(const std::string& item, const std::string& array, const std::string& index, uint32_t iteration) { XPathValue<std::string> arrayResult = _xpath.evaluate_expr(array, _doc); assert(arrayResult.type() == NODE_SET); #if 0 std::cout << "Array Size: " << arrayResult.asNodeSet().size() << std::endl; for (size_t i = 0; i < arrayResult.asNodeSet().size(); i++) { std::cout << arrayResult.asNodeSet()[i] << std::endl; } #endif assert(arrayResult.asNodeSet().size() >= iteration); NodeSet<std::string> arrayNodeSet; arrayNodeSet.push_back(arrayResult.asNodeSet()[iteration]); if (!isDeclared(item)) { if (!isValidIdentifier(item)) ERROR_EXECUTION_THROW("Expression '" + item + "' not a valid identifier."); Element<std::string> container = _doc.createElement("data"); container.setAttribute("id", item); container.appendChild(arrayResult.asNodeSet()[iteration].cloneNode(true)); _datamodel.appendChild(container); _varResolver.setVariable(item, arrayNodeSet); } XPathValue<std::string> itemResult = _varResolver.resolveVariable("", item); assign(itemResult, arrayNodeSet, Element<std::string>()); if (index.length() > 0) { NodeSet<std::string> indexNodeSet; Text<std::string> indexElem = _doc.createTextNode(toStr(iteration)); indexNodeSet.push_back(indexElem); if (!isDeclared(index)) { Element<std::string> container = _doc.createElement("data"); container.setAttribute("id", index); container.appendChild(indexElem); _datamodel.appendChild(container); NodeSet<std::string> indexVarNodeSet; indexVarNodeSet.push_back(container); _varResolver.setVariable(index, indexVarNodeSet); } XPathValue<std::string> indexResult = _varResolver.resolveVariable("", index); assign(indexResult, indexNodeSet, Element<std::string>()); } #if 0 std::cout << _datamodel << std::endl << std::endl; std::cout << "Index: " << indexResult.asNodeSet().size() << std::endl; for (size_t i = 0; i < indexResult.asNodeSet().size(); i++) { std::cout << indexResult.asNodeSet()[i] << std::endl; } std::cout << std::endl; #endif }
void C89DataModel::addExtension(DataModelExtension* ext) { ERROR_EXECUTION_THROW("Extensions unimplemented in C89 datamodel"); }