add class representing the node tree
add CParser class
This class holds the definitions of all the grammars. It also holds a reference a CTree instance it uses when parsing. This means, that it doesn't have to be declared globally.
Change-Id: I3ca23253b546e26612106067045e1e7d3e2ef919
diff --git a/src/CParser.cpp b/src/CParser.cpp
new file mode 100644
index 0000000..75af7c0
--- /dev/null
+++ b/src/CParser.cpp
@@ -0,0 +1,23 @@
+#include "CParser.hpp"
+
+TooManyArgumentsException::~TooManyArgumentsException() = default;
+
+CParser::CParser(const CTree& tree)
+ : m_tree(tree)
+{
+}
+
+
+Cmd CParser::parseInput(const std::string& line)
+{
+ Cmd args;
+ auto it = line.begin();
+ //bool result = x3::phrase_parse(it, line.end(), command, space, args);
+ //std::cout << "success: " << result << std::endl;
+ if (it != line.end()) {
+ throw TooManyArgumentsException(std::string(it, line.end()));
+ }
+
+
+ return args;
+}
diff --git a/src/CParser.hpp b/src/CParser.hpp
new file mode 100644
index 0000000..c3333af
--- /dev/null
+++ b/src/CParser.hpp
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2018 CESNET, https://photonics.cesnet.cz/
+ *
+ * Written by Václav Kubernát <kubervac@fit.cvut.cz>
+ *
+ */
+
+#pragma once
+#include <boost/spirit/home/x3.hpp>
+#include "CTree.hpp"
+namespace x3 = boost::spirit::x3;
+namespace ascii = boost::spirit::x3::ascii;
+using Cmd = std::vector<std::string>;
+using x3::alpha;
+using x3::lit;
+using x3::char_;
+using x3::_attr;
+using x3::lexeme;
+using ascii::space;
+
+class TooManyArgumentsException : public std::invalid_argument {
+public:
+ using std::invalid_argument::invalid_argument;
+ ~TooManyArgumentsException() override;
+};
+
+class CParser {
+public:
+ CParser(const CTree& tree);
+ Cmd parseInput(const std::string& line);
+
+private:
+ const CTree& m_tree;
+};
diff --git a/src/CTree.cpp b/src/CTree.cpp
new file mode 100644
index 0000000..994515a
--- /dev/null
+++ b/src/CTree.cpp
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2018 CESNET, https://photonics.cesnet.cz/
+ *
+ * Written by Václav Kubernát <kubervac@fit.cvut.cz>
+ *
+*/
+
+#include "CTree.hpp"
+
+InvalidNodeException::~InvalidNodeException() = default;
+
+std::string joinPaths(const std::string& prefix, const std::string& suffix)
+{
+ if (prefix.empty() || suffix.empty())
+ return prefix + suffix;
+ else
+ return prefix + '/' + suffix;
+}
+
+const std::unordered_set<std::string>& CTree::children(const std::string& node) const
+{
+ return m_nodes.at(node);
+}
+
+bool CTree::checkNode(const std::string& location, const std::string& node) const
+{
+ if (node == ".." || node.empty())
+ return true;
+ const auto& childrenRef = children(location); //first, get a reference to all children
+ if (childrenRef.find(node) == childrenRef.end()) { //find the desired node, if it isn't present throw an exception
+ throw InvalidNodeException(node);
+ }
+ return true;
+}
+void CTree::changeNode(const std::string& node)
+{
+ if (node.empty()) {
+ m_curDir = "";
+ return;
+ }
+ m_curDir += joinPaths(m_curDir, node);
+}
+std::string CTree::currentNode() const
+{
+ return m_curDir;
+}
+
+void CTree::addNode(const std::string& location, const std::string& name)
+{
+ m_nodes.at(location).insert(name);
+
+ //create a new set of children for the new node
+ m_nodes.emplace(joinPaths(location, name), std::unordered_set<std::string>());
+}
+void CTree::initDefault()
+{
+ m_nodes.emplace("", std::unordered_set<std::string>());
+ addNode("", "aaa");
+ addNode("", "bbb");
+ addNode("", "ccc");
+ addNode("aaa", "aaabbb");
+ addNode("aaa", "aaauuu");
+ addNode("bbb", "bbbuuu");
+}
diff --git a/src/CTree.hpp b/src/CTree.hpp
new file mode 100644
index 0000000..88bccae
--- /dev/null
+++ b/src/CTree.hpp
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2018 CESNET, https://photonics.cesnet.cz/
+ *
+ * Written by Václav Kubernát <kubervac@fit.cvut.cz>
+ *
+*/
+
+#pragma once
+
+#include <stdexcept>
+#include <unordered_map>
+#include <unordered_set>
+
+class InvalidNodeException : public std::invalid_argument {
+public:
+ using std::invalid_argument::invalid_argument;
+ ~InvalidNodeException() override;
+
+};
+
+/*! \class CTree
+ * \brief The class representing the tree, that the user traverses.
+ *
+ * This class holds the current position in the tree and handles changing the position,
+ * including checking what nodes are available.
+ * */
+class CTree {
+public:
+ bool checkNode(const std::string& location, const std::string& node) const;
+ void changeNode(const std::string& node);
+ void initDefault();
+ std::string currentNode() const;
+
+private:
+ void addNode(const std::string& location, const std::string& node);
+ const std::unordered_set<std::string>& children(const std::string& node) const;
+
+ std::unordered_map<std::string, std::unordered_set<std::string>> m_nodes;
+ std::string m_curDir;
+};
diff --git a/src/main.cpp b/src/main.cpp
index 3742e47..7e6d5f1 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -2,22 +2,47 @@
* Copyright (C) 2018 CESNET, https://photonics.cesnet.cz/
* Copyright (C) 2018 FIT CVUT, https://fit.cvut.cz/
*
- * Written by Jan Kundrát <jan.kundrat@cesnet.cz>
+ * Written by Václav Kubernát <kubervac@fit.cvut.cz>
*
*/
+#include <boost/spirit/home/x3.hpp>
#include <docopt.h>
+#include <iostream>
#include <string>
+#include "CParser.hpp"
+#include "CTree.hpp"
#include "NETCONF_CLI_VERSION.h"
+
static const char usage[] =
-R"(CLI interface to remote NETCONF hosts
+ R"(CLI interface to remote NETCONF hosts
Usage:
+ netconf-cli
netconf-cli (-h | --help)
netconf-cli --version
)";
+namespace x3 = boost::spirit::x3;
+namespace ascii = boost::spirit::x3::ascii;
+
+using Cmd = std::vector<std::string>;
+using x3::alpha;
+using x3::lit;
+using x3::char_;
+using x3::_attr;
+using x3::lexeme;
+using ascii::space;
+
+
+std::string getInput()
+{
+ std::string line;
+ std::getline(std::cin, line);
+ return line;
+}
+
int main(int argc, char* argv[])
{
auto args = docopt::docopt(usage,
@@ -25,5 +50,6 @@
true,
"netconf-cli " NETCONF_CLI_VERSION,
true);
+ std::cout << "Welcome to netconf-cli" << std::endl;
return 0;
}