tools: nfdc creates Face and KeyChain in main function
refs #3749
Change-Id: I169ad766634371b0192ebae640355298b78aaaa4
diff --git a/tests/tools/nfdc/command-parser.t.cpp b/tests/tools/nfdc/command-parser.t.cpp
index 435392d..73ad3cc 100644
--- a/tests/tools/nfdc/command-parser.t.cpp
+++ b/tests/tools/nfdc/command-parser.t.cpp
@@ -40,72 +40,62 @@
BOOST_AUTO_TEST_CASE(Basic)
{
CommandParser parser;
-
- std::string lastName;
- auto makeExecute = [&] (const std::string& name) {
- return [&, name] (const CommandArguments& args) {
- lastName = name;
- };
- };
+ ExecuteCommand dummyExecute = [] (ExecuteContext&) { return 0; };
CommandDefinition defHelp("help", "");
defHelp
.addArg("noun", ArgValueType::STRING, Required::NO, Positional::YES)
.addArg("verb", ArgValueType::STRING, Required::NO, Positional::YES);
- parser.addCommand(defHelp, makeExecute("help"), AVAILABLE_IN_ONE_SHOT);
+ parser.addCommand(defHelp, dummyExecute, AVAILABLE_IN_ONE_SHOT);
CommandDefinition defStatusShow("status", "show");
- parser.addCommand(defStatusShow, makeExecute("status show"));
+ parser.addCommand(defStatusShow, dummyExecute);
parser.addAlias("status", "show", "list");
BOOST_CHECK_THROW(parser.addAlias("status", "show2", "list"), std::out_of_range);
CommandDefinition defRouteList("route", "list");
defRouteList
.addArg("nexthop", ArgValueType::FACE_ID_OR_URI, Required::NO, Positional::YES);
- parser.addCommand(defRouteList, makeExecute("route list"));
+ parser.addCommand(defRouteList, dummyExecute);
CommandDefinition defRouteAdd("route", "add");
defRouteAdd
.addArg("prefix", ArgValueType::NAME, Required::YES, Positional::YES)
.addArg("nexthop", ArgValueType::FACE_ID_OR_URI, Required::YES, Positional::YES);
- parser.addCommand(defRouteAdd, makeExecute("route add"));
+ parser.addCommand(defRouteAdd, dummyExecute);
parser.addAlias("route", "add", "add2");
- CommandParser::Execute* execute = nullptr;
+ std::string noun, verb;
CommandArguments ca;
+ ExecuteCommand execute;
- std::tie(execute, ca) = parser.parse(std::vector<std::string>{"help"},
- ParseMode::ONE_SHOT);
- BOOST_REQUIRE(execute != nullptr);
- (*execute)(ca);
- BOOST_CHECK_EQUAL(lastName, "help");
+ std::tie(noun, verb, ca, execute) = parser.parse(
+ std::vector<std::string>{"help"}, ParseMode::ONE_SHOT);
+ BOOST_CHECK_EQUAL(noun, "help");
+ BOOST_CHECK_EQUAL(verb, "");
- std::tie(execute, ca) = parser.parse(std::vector<std::string>{"status"},
- ParseMode::ONE_SHOT);
- BOOST_REQUIRE(execute != nullptr);
- (*execute)(ca);
- BOOST_CHECK_EQUAL(lastName, "status show");
+ std::tie(noun, verb, ca, execute) = parser.parse(
+ std::vector<std::string>{"status"}, ParseMode::ONE_SHOT);
+ BOOST_CHECK_EQUAL(noun, "status");
+ BOOST_CHECK_EQUAL(verb, "show");
- std::tie(execute, ca) = parser.parse(std::vector<std::string>{"route", "add", "/n", "300"},
- ParseMode::ONE_SHOT);
- BOOST_REQUIRE(execute != nullptr);
- (*execute)(ca);
- BOOST_CHECK_EQUAL(lastName, "route add");
+ std::tie(noun, verb, ca, execute) = parser.parse(
+ std::vector<std::string>{"route", "add", "/n", "300"}, ParseMode::ONE_SHOT);
+ BOOST_CHECK_EQUAL(noun, "route");
+ BOOST_CHECK_EQUAL(verb, "add");
BOOST_CHECK_EQUAL(boost::any_cast<Name>(ca.at("prefix")), "/n");
BOOST_CHECK_EQUAL(boost::any_cast<uint64_t>(ca.at("nexthop")), 300);
- std::tie(execute, ca) = parser.parse(std::vector<std::string>{"route", "add2", "/n", "300"},
- ParseMode::ONE_SHOT);
- BOOST_REQUIRE(execute != nullptr);
- (*execute)(ca);
- BOOST_CHECK_EQUAL(lastName, "route add");
+ std::tie(noun, verb, ca, execute) = parser.parse(
+ std::vector<std::string>{"route", "add2", "/n", "300"}, ParseMode::ONE_SHOT);
+ BOOST_CHECK_EQUAL(noun, "route");
+ BOOST_CHECK_EQUAL(verb, "add");
- std::tie(execute, ca) = parser.parse(std::vector<std::string>{"route", "list", "400"},
- ParseMode::ONE_SHOT);
- BOOST_REQUIRE(execute != nullptr);
- (*execute)(ca);
- BOOST_CHECK_EQUAL(lastName, "route list");
+ std::tie(noun, verb, ca, execute) = parser.parse(
+ std::vector<std::string>{"route", "list", "400"}, ParseMode::ONE_SHOT);
+ BOOST_CHECK_EQUAL(noun, "route");
+ BOOST_CHECK_EQUAL(verb, "list");
BOOST_CHECK_EQUAL(boost::any_cast<uint64_t>(ca.at("nexthop")), 400);
BOOST_CHECK_THROW(parser.parse(std::vector<std::string>{}, ParseMode::ONE_SHOT),
@@ -120,7 +110,7 @@
CommandDefinition::Error);
}
-BOOST_AUTO_TEST_SUITE_END() // TestCommandDefinition
+BOOST_AUTO_TEST_SUITE_END() // TestCommandParser
BOOST_AUTO_TEST_SUITE_END() // Nfdc
} // namespace tests
diff --git a/tools/nfdc/available-commands.cpp b/tools/nfdc/available-commands.cpp
index 3b6a393..99a53e0 100644
--- a/tools/nfdc/available-commands.cpp
+++ b/tools/nfdc/available-commands.cpp
@@ -32,36 +32,25 @@
namespace tools {
namespace nfdc {
-static void
-statusReport(const CommandArguments& ca)
+static int
+statusReport(ExecuteContext& ctx)
{
- int res = 1;
- ReportFormat fmt = ca.get<ReportFormat>("format", ReportFormat::TEXT);
+ ReportFormat fmt = ctx.args.get<ReportFormat>("format", ReportFormat::TEXT);
switch (fmt) {
case ReportFormat::XML:
- res = statusMain(std::vector<std::string>{"-x"});
- break;
+ return statusMain(std::vector<std::string>{"-x"}, ctx.face, ctx.keyChain);
case ReportFormat::TEXT:
- res = statusMain(std::vector<std::string>{});
- break;
+ return statusMain(std::vector<std::string>{}, ctx.face, ctx.keyChain);
}
- exit(res);
+ BOOST_ASSERT(false);
+ return 1;
}
-static void
-legacyNfdStatus(const CommandArguments& ca)
+static int
+legacyNfdStatus(ExecuteContext& ctx)
{
- std::vector<std::string> args = ca.get<std::vector<std::string>>("args");
- int res = statusMain(args);
- exit(res);
-}
-
-static void
-legacyNfdc(const std::string& subcommand, const CommandArguments& ca)
-{
- std::vector<std::string> args = ca.get<std::vector<std::string>>("args");
- int res = legacyNfdcMain(subcommand, args);
- exit(res);
+ auto args = ctx.args.get<std::vector<std::string>>("args");
+ return statusMain(args, ctx.face, ctx.keyChain);
}
void
@@ -90,7 +79,7 @@
for (const std::string& subcommand : legacyNfdcSubcommands) {
CommandDefinition def(subcommand, "");
def.addArg("args", ArgValueType::ANY, Required::NO, Positional::YES);
- parser.addCommand(def, bind(&legacyNfdc, subcommand, _1));
+ parser.addCommand(def, &legacyNfdcMain);
}
}
diff --git a/tools/nfdc/command-definition.cpp b/tools/nfdc/command-definition.cpp
index cf11928..cb25c7c 100644
--- a/tools/nfdc/command-definition.cpp
+++ b/tools/nfdc/command-definition.cpp
@@ -104,7 +104,7 @@
bool isNew = m_args.emplace(name,
Arg{name, valueType, static_cast<bool>(isRequired),
metavar.empty() ? getMetavarFromType(valueType) : metavar}).second;
- BOOST_ASSERT(isNew);
+ BOOST_VERIFY(isNew);
if (static_cast<bool>(isRequired)) {
m_requiredArgs.insert(name);
diff --git a/tools/nfdc/command-parser.cpp b/tools/nfdc/command-parser.cpp
index d91cbc3..974c931 100644
--- a/tools/nfdc/command-parser.cpp
+++ b/tools/nfdc/command-parser.cpp
@@ -69,7 +69,7 @@
}
CommandParser&
-CommandParser::addCommand(const CommandDefinition& def, const Execute& execute, AvailableIn modes)
+CommandParser::addCommand(const CommandDefinition& def, const ExecuteCommand& execute, AvailableIn modes)
{
BOOST_ASSERT(modes != AVAILABLE_IN_NONE);
m_commands[{def.getNoun(), def.getVerb()}].reset(new Command{def, execute, modes});
@@ -83,7 +83,7 @@
return *this;
}
-std::tuple<CommandParser::Execute*, CommandArguments>
+std::tuple<std::string, std::string, CommandArguments, ExecuteCommand>
CommandParser::parse(const std::vector<std::string>& tokens, ParseMode mode) const
{
BOOST_ASSERT(mode == ParseMode::ONE_SHOT);
@@ -110,7 +110,7 @@
const CommandDefinition& def = i->second->def;
NDN_LOG_TRACE("found command " << def.getNoun() << " " << def.getVerb());
- return std::make_tuple(&i->second->execute, def.parse(tokens, nameLen));
+ return std::make_tuple(def.getNoun(), def.getVerb(), def.parse(tokens, nameLen), i->second->execute);
}
} // namespace nfdc
diff --git a/tools/nfdc/command-parser.hpp b/tools/nfdc/command-parser.hpp
index 7a1dbda..3a853c5 100644
--- a/tools/nfdc/command-parser.hpp
+++ b/tools/nfdc/command-parser.hpp
@@ -27,6 +27,7 @@
#define NFD_TOOLS_NFDC_COMMAND_PARSER_HPP
#include "command-definition.hpp"
+#include "execute-command.hpp"
namespace nfd {
namespace tools {
@@ -69,15 +70,13 @@
}
};
- typedef std::function<void(const CommandArguments&)> Execute;
-
/** \brief add an available command
* \param def command semantics definition
* \param execute a function to execute the command
* \param modes parse modes this command should be available in, must not be AVAILABLE_IN_NONE
*/
CommandParser&
- addCommand(const CommandDefinition& def, const Execute& execute, AvailableIn modes = AVAILABLE_IN_ALL);
+ addCommand(const CommandDefinition& def, const ExecuteCommand& execute, AvailableIn modes = AVAILABLE_IN_ALL);
/** \brief add an alias "noun verb2" to existing command "noun verb"
* \throw std::out_of_range "noun verb" does not exist
@@ -90,8 +89,9 @@
* \param mode parser mode, must be ParseMode::ONE_SHOT, other modes are not implemented
* \throw Error command is not found
* \throw CommandDefinition::Error command arguments are invalid
+ * \return noun, verb, arguments, execute function
*/
- std::tuple<Execute*, CommandArguments>
+ std::tuple<std::string, std::string, CommandArguments, ExecuteCommand>
parse(const std::vector<std::string>& tokens, ParseMode mode) const;
private:
@@ -100,7 +100,7 @@
struct Command
{
CommandDefinition def;
- Execute execute;
+ ExecuteCommand execute;
AvailableIn modes;
};
diff --git a/tools/nfdc/execute-command.hpp b/tools/nfdc/execute-command.hpp
new file mode 100644
index 0000000..31b2d52
--- /dev/null
+++ b/tools/nfdc/execute-command.hpp
@@ -0,0 +1,62 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014-2016, Regents of the University of California,
+ * Arizona Board of Regents,
+ * Colorado State University,
+ * University Pierre & Marie Curie, Sorbonne University,
+ * Washington University in St. Louis,
+ * Beijing Institute of Technology,
+ * The University of Memphis.
+ *
+ * This file is part of NFD (Named Data Networking Forwarding Daemon).
+ * See AUTHORS.md for complete list of NFD authors and contributors.
+ *
+ * NFD is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ *
+ * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * NFD, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef NFD_TOOLS_NFDC_EXECUTE_COMMAND_HPP
+#define NFD_TOOLS_NFDC_EXECUTE_COMMAND_HPP
+
+#include "command-arguments.hpp"
+#include <ndn-cxx/face.hpp>
+#include <ndn-cxx/security/key-chain.hpp>
+
+namespace nfd {
+namespace tools {
+namespace nfdc {
+
+using ndn::Face;
+using ndn::KeyChain;
+
+/** \brief context for command execution
+ */
+struct ExecuteContext
+{
+ const std::string& noun;
+ const std::string& verb;
+ const CommandArguments& args;
+
+ Face& face;
+ KeyChain& keyChain;
+ ///\todo validator
+};
+
+/** \brief a function to execute a command
+ * \return exit code
+ */
+typedef std::function<int(ExecuteContext& ctx)> ExecuteCommand;
+
+} // namespace nfdc
+} // namespace tools
+} // namespace nfd
+
+#endif // NFD_TOOLS_NFDC_EXECUTE_COMMAND_HPP
diff --git a/tools/nfdc/legacy-nfdc.cpp b/tools/nfdc/legacy-nfdc.cpp
index 5b7ff45..f5c4fa7 100644
--- a/tools/nfdc/legacy-nfdc.cpp
+++ b/tools/nfdc/legacy-nfdc.cpp
@@ -38,14 +38,14 @@
const time::milliseconds LegacyNfdc::DEFAULT_EXPIRATION_PERIOD = time::milliseconds::max();
const uint64_t LegacyNfdc::DEFAULT_COST = 0;
-LegacyNfdc::LegacyNfdc(ndn::Face& face)
+LegacyNfdc::LegacyNfdc(Face& face, KeyChain& keyChain)
: m_flags(ndn::nfd::ROUTE_FLAG_CHILD_INHERIT)
, m_cost(DEFAULT_COST)
, m_origin(ndn::nfd::ROUTE_ORIGIN_STATIC)
, m_expires(DEFAULT_EXPIRATION_PERIOD)
, m_facePersistency(ndn::nfd::FACE_PERSISTENCY_PERSISTENT)
, m_face(face)
- , m_controller(face, m_keyChain)
+ , m_controller(face, keyChain)
{
}
@@ -326,11 +326,12 @@
}
int
-legacyNfdcMain(const std::string& subcommand, const std::vector<std::string>& args)
+legacyNfdcMain(ExecuteContext& ctx)
{
- ndn::Face face;
- LegacyNfdc p(face);
+ LegacyNfdc p(ctx.face, ctx.keyChain);
+ const std::string& subcommand = ctx.noun;
+ auto args = ctx.args.get<std::vector<std::string>>("args");
bool wantUnsetChildInherit = false;
bool wantCapture = false;
bool wantPermanentFace = false;
@@ -381,18 +382,12 @@
}
p.m_commandLineArguments = unparsed;
- try {
- bool isOk = p.dispatch(subcommand);
- if (!isOk) {
- legacyNfdcUsage();
- return 1;
- }
- face.processEvents();
+ bool isOk = p.dispatch(subcommand);
+ if (!isOk) {
+ legacyNfdcUsage();
+ return 1;
}
- catch (const std::exception& e) {
- std::cerr << "ERROR: " << e.what() << std::endl;
- return 2;
- }
+ ctx.face.processEvents();
return 0;
}
diff --git a/tools/nfdc/legacy-nfdc.hpp b/tools/nfdc/legacy-nfdc.hpp
index 1c3772b..9acb228 100644
--- a/tools/nfdc/legacy-nfdc.hpp
+++ b/tools/nfdc/legacy-nfdc.hpp
@@ -26,9 +26,7 @@
#ifndef NFD_TOOLS_NFDC_LEGACY_NFDC_HPP
#define NFD_TOOLS_NFDC_LEGACY_NFDC_HPP
-#include "core/common.hpp"
-#include <ndn-cxx/face.hpp>
-#include <ndn-cxx/security/key-chain.hpp>
+#include "execute-command.hpp"
#include <ndn-cxx/mgmt/nfd/controller.hpp>
namespace nfd {
@@ -51,8 +49,7 @@
}
};
- explicit
- LegacyNfdc(ndn::Face& face);
+ LegacyNfdc(Face& face, KeyChain& keyChain);
bool
dispatch(const std::string& cmd);
@@ -169,8 +166,7 @@
ndn::nfd::FacePersistency m_facePersistency;
private:
- ndn::KeyChain m_keyChain;
- ndn::Face& m_face;
+ Face& m_face;
ndn::nfd::Controller m_controller;
};
@@ -178,7 +174,7 @@
legacyNfdcUsage();
int
-legacyNfdcMain(const std::string& subcommand, const std::vector<std::string>& args);
+legacyNfdcMain(ExecuteContext& ctx);
} // namespace nfdc
} // namespace tools
diff --git a/tools/nfdc/main.cpp b/tools/nfdc/main.cpp
index 85fe1e9..c578407 100644
--- a/tools/nfdc/main.cpp
+++ b/tools/nfdc/main.cpp
@@ -48,21 +48,27 @@
CommandParser parser;
registerCommands(parser);
- CommandParser::Execute* execute = nullptr;
+ std::string noun, verb;
CommandArguments ca;
+ ExecuteCommand execute;
try {
- std::tie(execute, ca) = parser.parse(args, ParseMode::ONE_SHOT);
+ std::tie(noun, verb, ca, execute) = parser.parse(args, ParseMode::ONE_SHOT);
}
catch (const std::invalid_argument& e) {
std::cerr << e.what() << std::endl;
return 1;
}
- ///\todo create Face and KeyChain here
- (*execute)(ca);
- ///\todo call processEvents here
- ///\todo return proper exit code here, instead of using exit() in subcommand
- return 0;
+ try {
+ ndn::Face face;
+ ndn::KeyChain keyChain;
+ ExecuteContext ctx{noun, verb, ca, face, keyChain};
+ return execute(ctx);
+ }
+ catch (const std::exception& e) {
+ std::cerr << e.what() << std::endl;
+ return 1;
+ }
}
} // namespace nfdc
diff --git a/tools/nfdc/status-main.cpp b/tools/nfdc/status-main.cpp
index 0f87ab1..c39f694 100644
--- a/tools/nfdc/status-main.cpp
+++ b/tools/nfdc/status-main.cpp
@@ -114,7 +114,7 @@
}
int
-statusMain(const std::vector<std::string>& args)
+statusMain(const std::vector<std::string>& args, Face& face, KeyChain& keyChain)
{
int exitCode = -1;
Options options;
@@ -123,8 +123,6 @@
return exitCode;
}
- Face face;
- KeyChain keyChain;
unique_ptr<Validator> validator = make_unique<ndn::ValidatorNull>();
CommandOptions ctrlOptions;
diff --git a/tools/nfdc/status-main.hpp b/tools/nfdc/status-main.hpp
index 62b58a6..8294a2c 100644
--- a/tools/nfdc/status-main.hpp
+++ b/tools/nfdc/status-main.hpp
@@ -26,14 +26,14 @@
#ifndef NFD_TOOLS_NFDC_STATUS_MAIN_HPP
#define NFD_TOOLS_NFDC_STATUS_MAIN_HPP
-#include "core/common.hpp"
+#include "execute-command.hpp"
namespace nfd {
namespace tools {
namespace nfdc {
int
-statusMain(const std::vector<std::string>& args);
+statusMain(const std::vector<std::string>& args, Face& face, KeyChain& keyChain);
} // namespace nfdc
} // namespace tools