From 8db5ff97ffe34aa42f71b5c8aebfa0878e5fde89 Mon Sep 17 00:00:00 2001 From: Bent Bisballe Nyeng Date: Sat, 4 Jul 2020 16:58:08 +0200 Subject: Add error message support and reporting on all commands. --- src/nodetree.cc | 266 +++++++++++++++++++++++++++----------------------------- 1 file changed, 128 insertions(+), 138 deletions(-) (limited to 'src/nodetree.cc') diff --git a/src/nodetree.cc b/src/nodetree.cc index a2499ea..f0877ff 100644 --- a/src/nodetree.cc +++ b/src/nodetree.cc @@ -34,6 +34,7 @@ #include "hugin.hpp" #include "xml_encode_decode.h" +#include "exceptions.h" #define ROOT_PARENT_ID -1 @@ -75,22 +76,14 @@ std::string Node::toXML(std::string prefix) static void concatNodeIdLists(NodeIdList& pre, NodeIdList& post) { pre.insert(pre.end(), post.begin(), post.end()); - //for(NodeIdList::iterator it = post.begin(); - //it != post.end(); it++) - //{ - // pre.push_back( - //} } NodeTree::NodeTree() { - root = NULL; - nextid = 10; } NodeTree::~NodeTree() { - // cleanup tree } nodeid_t NodeTree::createId() @@ -106,7 +99,7 @@ nodeid_t NodeTree::createId() return nodeid; } -bool NodeTree::hasId(nodeid_t nodeid) +bool NodeTree::hasId(nodeid_t nodeid) const { return id2node.find(nodeid) != id2node.end(); } @@ -115,11 +108,15 @@ static nodeid_t rootid = -1; NodeIdList NodeTree::insertAsChild(nodeid_t parentid, nodeid_t id, node_t data, nodeid_t insertBeforeId) - throw (std::exception) { NodeIdList affectedNodes; - // Initialize + if(parentid == id) + { + throw Error::NewParentIsSelf(); // Node and new parent are the same node. + } + + // Initialized? if(!root) { rootid = id; @@ -130,62 +127,46 @@ NodeIdList NodeTree::insertAsChild(nodeid_t parentid, nodeid_t id, } else { - try + if(!hasId(parentid)) { - Node* parent = id2node.at(parentid); - Node* child = createNode(id); - //DEBUG(nodetree, "!!!!!!!id in insert: %d\n", data.id); - child->data = data; - insertChild(parent, child, insertBeforeId); - - //affectedNodes.push_back(parentid); - affectedNodes.push_back(id); - NodeIdList ancestors = ancestorList(id); - concatNodeIdLists(affectedNodes, ancestors); - } - catch(std::exception& e) - { - throw e; + throw Error::MissingParent(); } + + Node* parent = id2node.at(parentid); + Node* child = createNode(id); + + child->data = data; + insertChild(parent, child, insertBeforeId); + affectedNodes.push_back(id); + + NodeIdList ancestors = ancestorList(id); + concatNodeIdLists(affectedNodes, ancestors); } - //DEBUG(nodetree, "Child %d added to %d, affecting %d nodes\n", - // id, parentid, affectedNodes.size()); return affectedNodes; } NodeIdList NodeTree::remove(nodeid_t id) - throw (std::exception) { + if(!hasId(id)) + { + throw Error::NoSuchId(); + } + NodeIdList affectedNodes; affectedNodes.push_back(id); NodeIdList ancestors = ancestorList(id); concatNodeIdLists(affectedNodes, ancestors); - //DEBUG(nodetree, "Removing %d\n", id); - //DEBUG(nodetree, "!!!!!affected nodes %d\n", affectedNodes.size()); - - Node* node = id2node[id]; - - //DEBUG(nodetree, "node: %p, id %d, parent %p\n", node, node->data.id, node->parent); + Node* node = id2node.at(id); - //DEBUG(nodetree, "!!!!!size %d\n", node->parent->children.size()); node->parent->children.remove(node); - for(NodeList::iterator it = node->parent->children.begin(); - it != node->parent->children.end(); - it++) - { - //DEBUG(nodetree, "%p\n", *it); - } - //DEBUG(nodetree, "!!!!!size %d\n", node->parent->children.size()); NodeIdList idlist = bfs(id); NodeIdList::reverse_iterator it = idlist.rbegin(); while(it != idlist.rend()) { node_t node = data(*it); - //Node* n = id2node[node.id]; - //delete(n); it++; } @@ -208,112 +189,114 @@ static bool findNode(Node *needle, Node *haystack) } NodeIdList NodeTree::move(nodeid_t id, nodeid_t toid, nodeid_t beforeId) - throw (std::exception) { NodeIdList affectedNodes; - try + if(id == toid) { - Node* child = id2node.at(id); - Node* newparent = id2node.at(toid); + throw Error::NewParentIsSelf(); // Node and new parent are the same node. + } - // Test if new parent is a child of the node itself... - if(findNode(newparent, child)) - { - throw std::exception(); - } + if(!hasId(id)) + { + throw Error::NoSuchId(); + } - if(!child->parent) - { - throw std::exception(); - } + Node* child = id2node.at(id); - child->parent->children.remove(child); - bool inserted{false}; - for(auto it = newparent->children.begin(); - it != newparent->children.end(); - ++it) - { - if((*it)->id == beforeId) - { - newparent->children.insert(it, child); - inserted = true; - } - } - if(!inserted) - { - // beforeId was not found in parent - inserting last instead. - newparent->children.push_back(child); - } + if(!hasId(toid)) + { + throw Error::MissingParent(); + } - child->parent = newparent; + Node* newparent = id2node.at(toid); - affectedNodes.push_back(id); - // affectedNodes.push_back(child->parent->id); - NodeIdList ancestors = ancestorList(id); - concatNodeIdLists(affectedNodes, ancestors); - affectedNodes.push_back(toid); - ancestors = ancestorList(toid); + // Test if new parent is a child of the node itself... + if(findNode(newparent, child)) + { + throw Error::NewParentIsChildOfSelf(); + } + + if(!child->parent) + { + throw Error::System("Node does not have a parent."); + } + + child->parent->children.remove(child); + bool inserted{false}; + for(auto it = newparent->children.begin(); + it != newparent->children.end(); + ++it) + { + if((*it)->id == beforeId) + { + newparent->children.insert(it, child); + inserted = true; + } } - catch(std::exception& e) + if(!inserted) { - throw e; + // beforeId was not found in parent - inserting last instead. + newparent->children.push_back(child); } + child->parent = newparent; + + affectedNodes.push_back(id); + + NodeIdList ancestors = ancestorList(id); + concatNodeIdLists(affectedNodes, ancestors); + affectedNodes.push_back(toid); + ancestors = ancestorList(toid); + return affectedNodes; } NodeIdList NodeTree::updateData(nodeid_t id, const std::string &name, const std::string &value) - throw (std::exception) { + if(!hasId(id)) + { + throw Error::NoSuchId(); + } + NodeIdList affectedNodes; - try - { - Node* node = id2node.at(id); - node->data.attributes[name] = value; + Node* node = id2node.at(id); + node->data.attributes[name] = value; - affectedNodes.push_back(id); - NodeIdList ancestors = ancestorList(id); - concatNodeIdLists(affectedNodes, ancestors); - } - catch(std::exception& e) - { - throw e; - } + affectedNodes.push_back(id); + NodeIdList ancestors = ancestorList(id); + concatNodeIdLists(affectedNodes, ancestors); return affectedNodes; } node_t NodeTree::data(nodeid_t id) - throw (std::exception) { + if(!hasId(id)) + { + throw Error::NoSuchId(); + } + node_t t; - try + Node* node = id2node.at(id); + node_t tmp = node->data; + t.id = node->id; + t.attributes = tmp.attributes; + + if(node->parent) { - Node* node = id2node.at(id); - node_t tmp = node->data; - t.id = node->id; - t.attributes = tmp.attributes; - //DEBUG(nodetree, "!!!!t.id and tmp.id in data: %d and %d\n", t.id, tmp.id); - if(node->parent) - { - t.parentid = node->parent->id; - } - else - { - if(t.id != rootid) - { - throw std::exception(); - } - t.parentid = -1; - } + t.parentid = node->parent->id; } - catch(std::exception& e) + else { - throw e; + if(t.id != rootid) + { + throw Error::System("Node has no parent, but node is not root."); + } + t.parentid = -1; } return t; @@ -321,8 +304,12 @@ node_t NodeTree::data(nodeid_t id) // bfs search from id in tree NodeIdList NodeTree::bfs(nodeid_t id) - throw (std::exception) { + if(!hasId(id)) + { + throw Error::NoSuchId(); + } + NodeIdList lst; lst.push_back(id); @@ -353,35 +340,36 @@ NodeIdList NodeTree::bfs(nodeid_t id) } NodeIdList NodeTree::ancestorList(nodeid_t id) - throw (std::exception) { NodeIdList ancestors; - try + if(!hasId(id)) { - Node* current = id2node.at(id); - while(current->parent) - { - ancestors.push_back(current->parent->id); - current = current->parent; - } + throw Error::NoSuchId(); } - catch(std::exception& e) + + Node* current = id2node.at(id); + auto origin = current; + while(current->parent) { - throw e; + ancestors.push_back(current->parent->id); + current = current->parent; + if(current == origin) + { + throw Error::System("Cycle detected."); + } } - //DEBUG(nodetree, "Collected %d ancestors to %u\n", ancestors.size(), id); - //for(NodeIdList::iterator it = ancestors.begin(); - // it != ancestors.end(); it++) - //{ - // DEBUG(nodetree, "\tancestor %u\n", *it); - //} return ancestors; } Node* NodeTree::createNode(nodeid_t id) { + if(hasId(id)) + { + throw Error::IdAlreadyExists(); + } + Node* node = new Node(); node->parent = NULL; node->id = id; @@ -425,6 +413,7 @@ static void printNode(Node* node, std::string prefix) { return; } + node_t t = node->data; DEBUG(nodetree, "%s- %u - %s (%p)\n", prefix.c_str(), (int)node->id, t.attributes["title"].c_str(), node); @@ -444,12 +433,13 @@ void NodeTree::toStdOut() std::string NodeTree::toXML() { - Node *root = id2node.at(rootid); - std::string xml; xml += "\n"; xml += "\n"; - xml += root->toXML(" "); + if(root) + { + xml += root->toXML(" "); + } xml += ""; return xml; -- cgit v1.2.3