diff --git a/docs/manpages/nfdc-cs.rst b/docs/manpages/nfdc-cs.rst index cef31b82..4ff387c8 100644 --- a/docs/manpages/nfdc-cs.rst +++ b/docs/manpages/nfdc-cs.rst @@ -3,7 +3,7 @@ nfdc-cs SYNOPSIS -------- -| nfdc cs info +| nfdc cs [info] DESCRIPTION ----------- diff --git a/docs/manpages/nfdc-face.rst b/docs/manpages/nfdc-face.rst index 37c6c066..f9dd1fd0 100644 --- a/docs/manpages/nfdc-face.rst +++ b/docs/manpages/nfdc-face.rst @@ -5,7 +5,10 @@ SYNOPSIS -------- | nfdc face [list [[remote] ] [local ] [scheme ]] | nfdc face show [id] -| nfdc face create [remote] [[persistency] ] [local ] [reliability on|off] [congestion-marking on|off] [congestion-marking-interval ] [default-congestion-threshold ] +| nfdc face create [remote] [[persistency] ] [local ] +| [reliability on|off] [congestion-marking on|off] +| [congestion-marking-interval ] +| [default-congestion-threshold ] | nfdc face destroy [face] | nfdc channel [list] diff --git a/docs/manpages/nfdc-route.rst b/docs/manpages/nfdc-route.rst index cbaf2bf9..3b284398 100644 --- a/docs/manpages/nfdc-route.rst +++ b/docs/manpages/nfdc-route.rst @@ -5,8 +5,8 @@ SYNOPSIS -------- | nfdc route [list [[nexthop] ] [origin ]] | nfdc route show [prefix] -| nfdc route add [prefix] [nexthop] [origin ] [cost ] -| [no-inherit] [capture] [expires ] +| nfdc route add [prefix] [nexthop] [origin ] +| [cost ] [no-inherit] [capture] [expires ] | nfdc route remove [prefix] [nexthop] [origin ] | nfdc fib [list] diff --git a/tests/tools/nfdc/command-definition.t.cpp b/tests/tools/nfdc/command-definition.t.cpp index 34b59695..374e36de 100644 --- a/tests/tools/nfdc/command-definition.t.cpp +++ b/tests/tools/nfdc/command-definition.t.cpp @@ -1,6 +1,6 @@ /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ -/** - * Copyright (c) 2014-2017, Regents of the University of California, +/* + * Copyright (c) 2014-2018, Regents of the University of California, * Arizona Board of Regents, * Colorado State University, * University Pierre & Marie Curie, Sorbonne University, @@ -144,6 +144,8 @@ BOOST_AUTO_TEST_SUITE(ParseValue) BOOST_AUTO_TEST_CASE(NoneType) { + BOOST_CHECK_EQUAL(boost::lexical_cast(ArgValueType::NONE), "none"); + CommandDefinition cs("noun", "verb"); cs.addArg("a", ArgValueType::NONE, Required::YES, Positional::NO); @@ -159,6 +161,8 @@ BOOST_AUTO_TEST_CASE(NoneType) BOOST_AUTO_TEST_CASE(AnyType) { + BOOST_CHECK_EQUAL(boost::lexical_cast(ArgValueType::ANY), "any"); + CommandDefinition cs("noun", "verb"); cs.addArg("a", ArgValueType::ANY, Required::NO, Positional::YES); @@ -183,8 +187,42 @@ BOOST_AUTO_TEST_CASE(AnyType) BOOST_CHECK_EQUAL(values.at(1), "c"); } +BOOST_AUTO_TEST_CASE(BooleanType) +{ + BOOST_CHECK_EQUAL(boost::lexical_cast(ArgValueType::BOOLEAN), "boolean"); + + CommandDefinition cs("noun", "verb"); + cs.addArg("a", ArgValueType::BOOLEAN, Required::YES); + + CommandArguments ca; + + ca = cs.parse({"a", "on"}); + BOOST_CHECK_EQUAL(ca.size(), 1); + BOOST_CHECK(ca.at("a").type() == typeid(bool)); + BOOST_CHECK_EQUAL(ca.get("a"), true); + + ca = cs.parse({"a", "off"}); + BOOST_CHECK_EQUAL(ca.size(), 1); + BOOST_CHECK(ca.at("a").type() == typeid(bool)); + BOOST_CHECK_EQUAL(ca.get("a"), false); + + BOOST_CHECK_EQUAL(cs.parse({"a", "true"}).get("a"), true); + BOOST_CHECK_EQUAL(cs.parse({"a", "enabled"}).get("a"), true); + BOOST_CHECK_EQUAL(cs.parse({"a", "yes"}).get("a"), true); + BOOST_CHECK_EQUAL(cs.parse({"a", "1"}).get("a"), true); + BOOST_CHECK_EQUAL(cs.parse({"a", "false"}).get("a"), false); + BOOST_CHECK_EQUAL(cs.parse({"a", "disabled"}).get("a"), false); + BOOST_CHECK_EQUAL(cs.parse({"a", "no"}).get("a"), false); + BOOST_CHECK_EQUAL(cs.parse({"a", "0"}).get("a"), false); + + BOOST_CHECK_THROW(cs.parse({"a", "42"}), CommandDefinition::Error); + BOOST_CHECK_THROW(cs.parse({"a", "not-bool"}), CommandDefinition::Error); +} + BOOST_AUTO_TEST_CASE(UnsignedType) { + BOOST_CHECK_EQUAL(boost::lexical_cast(ArgValueType::UNSIGNED), "non-negative integer"); + CommandDefinition cs("noun", "verb"); cs.addArg("a", ArgValueType::UNSIGNED, Required::YES); @@ -206,6 +244,8 @@ BOOST_AUTO_TEST_CASE(UnsignedType) BOOST_AUTO_TEST_CASE(StringType) { + BOOST_CHECK_EQUAL(boost::lexical_cast(ArgValueType::STRING), "string"); + CommandDefinition cs("noun", "verb"); cs.addArg("a", ArgValueType::STRING, Required::YES); @@ -219,6 +259,8 @@ BOOST_AUTO_TEST_CASE(StringType) BOOST_AUTO_TEST_CASE(ReportFormatType) { + BOOST_CHECK_EQUAL(boost::lexical_cast(ArgValueType::REPORT_FORMAT), "ReportFormat"); + CommandDefinition cs("noun", "verb"); cs.addArg("a", ArgValueType::REPORT_FORMAT, Required::YES); @@ -239,6 +281,8 @@ BOOST_AUTO_TEST_CASE(ReportFormatType) BOOST_AUTO_TEST_CASE(NameType) { + BOOST_CHECK_EQUAL(boost::lexical_cast(ArgValueType::NAME), "Name"); + CommandDefinition cs("noun", "verb"); cs.addArg("a", ArgValueType::NAME, Required::YES); @@ -252,6 +296,8 @@ BOOST_AUTO_TEST_CASE(NameType) BOOST_AUTO_TEST_CASE(FaceUriType) { + BOOST_CHECK_EQUAL(boost::lexical_cast(ArgValueType::FACE_URI), "FaceUri"); + CommandDefinition cs("noun", "verb"); cs.addArg("a", ArgValueType::FACE_URI, Required::YES); @@ -268,6 +314,8 @@ BOOST_AUTO_TEST_CASE(FaceUriType) BOOST_AUTO_TEST_CASE(FaceIdOrUriType) { + BOOST_CHECK_EQUAL(boost::lexical_cast(ArgValueType::FACE_ID_OR_URI), "FaceId or FaceUri"); + CommandDefinition cs("noun", "verb"); cs.addArg("a", ArgValueType::FACE_ID_OR_URI, Required::YES); @@ -288,6 +336,8 @@ BOOST_AUTO_TEST_CASE(FaceIdOrUriType) BOOST_AUTO_TEST_CASE(FacePersistencyType) { + BOOST_CHECK_EQUAL(boost::lexical_cast(ArgValueType::FACE_PERSISTENCY), "FacePersistency"); + CommandDefinition cs("noun", "verb"); cs.addArg("a", ArgValueType::FACE_PERSISTENCY, Required::YES); @@ -296,14 +346,12 @@ BOOST_AUTO_TEST_CASE(FacePersistencyType) ca = cs.parse(std::vector{"a", "persistent"}); BOOST_CHECK_EQUAL(ca.size(), 1); BOOST_CHECK(ca.at("a").type() == typeid(FacePersistency)); - BOOST_CHECK_EQUAL(ca.get("a"), - FacePersistency::FACE_PERSISTENCY_PERSISTENT); + BOOST_CHECK_EQUAL(ca.get("a"), FacePersistency::FACE_PERSISTENCY_PERSISTENT); ca = cs.parse(std::vector{"a", "permanent"}); BOOST_CHECK_EQUAL(ca.size(), 1); BOOST_CHECK(ca.at("a").type() == typeid(FacePersistency)); - BOOST_CHECK_EQUAL(ca.get("a"), - FacePersistency::FACE_PERSISTENCY_PERMANENT); + BOOST_CHECK_EQUAL(ca.get("a"), FacePersistency::FACE_PERSISTENCY_PERMANENT); // nfdc does not accept "on-demand" BOOST_CHECK_THROW(cs.parse(std::vector{"a", "on-demand"}), CommandDefinition::Error); @@ -311,6 +359,8 @@ BOOST_AUTO_TEST_CASE(FacePersistencyType) BOOST_AUTO_TEST_CASE(RouteOriginType) { + BOOST_CHECK_EQUAL(boost::lexical_cast(ArgValueType::ROUTE_ORIGIN), "RouteOrigin"); + CommandDefinition cs("noun", "verb"); cs.addArg("a", ArgValueType::ROUTE_ORIGIN, Required::YES); @@ -319,14 +369,12 @@ BOOST_AUTO_TEST_CASE(RouteOriginType) ca = cs.parse(std::vector{"a", "Nlsr"}); BOOST_CHECK_EQUAL(ca.size(), 1); BOOST_CHECK(ca.at("a").type() == typeid(RouteOrigin)); - BOOST_CHECK_EQUAL(ca.get("a"), - RouteOrigin::ROUTE_ORIGIN_NLSR); + BOOST_CHECK_EQUAL(ca.get("a"), RouteOrigin::ROUTE_ORIGIN_NLSR); ca = cs.parse(std::vector{"a", "27"}); BOOST_CHECK_EQUAL(ca.size(), 1); BOOST_CHECK(ca.at("a").type() == typeid(RouteOrigin)); - BOOST_CHECK_EQUAL(ca.get("a"), - static_cast(27)); + BOOST_CHECK_EQUAL(ca.get("a"), static_cast(27)); BOOST_CHECK_THROW(cs.parse(std::vector{"a", "not-RouteOrigin"}), CommandDefinition::Error); } diff --git a/tests/tools/nfdc/command-parser.t.cpp b/tests/tools/nfdc/command-parser.t.cpp index 47aa815f..ddf96533 100644 --- a/tests/tools/nfdc/command-parser.t.cpp +++ b/tests/tools/nfdc/command-parser.t.cpp @@ -60,14 +60,12 @@ BOOST_AUTO_TEST_CASE(Basic) BOOST_CHECK(parser.listCommands("", ParseMode::ONE_SHOT).empty()); - CommandDefinition defHelp("help", ""); - defHelp - .addArg("noun", ArgValueType::STRING, Required::NO, Positional::YES) - .addArg("verb", ArgValueType::STRING, Required::NO, Positional::YES); - parser.addCommand(defHelp, dummyExecute, AVAILABLE_IN_ONE_SHOT | AVAILABLE_IN_HELP); + CommandDefinition defFoo("foo", ""); + parser.addCommand(defFoo, dummyExecute, AVAILABLE_IN_ONE_SHOT | AVAILABLE_IN_HELP); CommandDefinition defStatusShow("status", "show"); parser.addCommand(defStatusShow, dummyExecute); + parser.addAlias("status", "show", ""); parser.addAlias("status", "show", "list"); BOOST_CHECK_THROW(parser.addAlias("status", "show2", "list"), std::out_of_range); @@ -75,6 +73,7 @@ BOOST_AUTO_TEST_CASE(Basic) defRouteList .addArg("nexthop", ArgValueType::FACE_ID_OR_URI, Required::NO, Positional::YES); parser.addCommand(defRouteList, dummyExecute); + parser.addAlias("route", "list", ""); CommandDefinition defRouteAdd("route", "add"); defRouteAdd @@ -95,18 +94,18 @@ BOOST_AUTO_TEST_CASE(Basic) CommandArguments ca; ExecuteCommand execute; - std::tie(noun, verb, ca, execute) = parser.parse({"help"}, ParseMode::ONE_SHOT); - BOOST_CHECK_EQUAL(noun, "help"); - BOOST_CHECK_EQUAL(verb, ""); - - std::tie(noun, verb, ca, execute) = parser.parse({"help", "foo"}, ParseMode::ONE_SHOT); - BOOST_CHECK_EQUAL(noun, "help"); + std::tie(noun, verb, ca, execute) = parser.parse({"foo"}, ParseMode::ONE_SHOT); + BOOST_CHECK_EQUAL(noun, "foo"); BOOST_CHECK_EQUAL(verb, ""); std::tie(noun, verb, ca, execute) = parser.parse({"status"}, ParseMode::ONE_SHOT); BOOST_CHECK_EQUAL(noun, "status"); BOOST_CHECK_EQUAL(verb, "show"); + std::tie(noun, verb, ca, execute) = parser.parse({"status", "list"}, ParseMode::ONE_SHOT); + BOOST_CHECK_EQUAL(noun, "status"); + BOOST_CHECK_EQUAL(verb, "show"); + std::tie(noun, verb, ca, execute) = parser.parse({"route", "add", "/n", "300"}, ParseMode::ONE_SHOT); BOOST_CHECK_EQUAL(noun, "route"); BOOST_CHECK_EQUAL(verb, "add"); @@ -124,10 +123,12 @@ BOOST_AUTO_TEST_CASE(Basic) BOOST_CHECK_THROW(parser.parse({}, ParseMode::ONE_SHOT), CommandParser::NoSuchCommandError); - BOOST_CHECK_THROW(parser.parse({"cant-help"}, ParseMode::ONE_SHOT), + BOOST_CHECK_THROW(parser.parse({"bar"}, ParseMode::ONE_SHOT), CommandParser::NoSuchCommandError); BOOST_CHECK_THROW(parser.parse({"status", "hide"}, ParseMode::ONE_SHOT), CommandParser::NoSuchCommandError); + BOOST_CHECK_THROW(parser.parse({"status", "show", "something"}, ParseMode::ONE_SHOT), + CommandDefinition::Error); BOOST_CHECK_THROW(parser.parse({"route", "66"}, ParseMode::ONE_SHOT), CommandParser::NoSuchCommandError); BOOST_CHECK_THROW(parser.parse({"route", "add"}, ParseMode::ONE_SHOT), diff --git a/tools/nfdc/command-parser.cpp b/tools/nfdc/command-parser.cpp index 59c49124..a2012723 100644 --- a/tools/nfdc/command-parser.cpp +++ b/tools/nfdc/command-parser.cpp @@ -114,24 +114,10 @@ CommandParser::parse(const std::vector& tokens, ParseMode mode) con const std::string& noun = tokens.size() > 0 ? tokens[0] : ""; const std::string& verb = tokens.size() > 1 ? tokens[1] : ""; - size_t nameLen = std::min(2, tokens.size()); NDN_LOG_TRACE("parse mode=" << mode << " noun=" << noun << " verb=" << verb); auto i = m_commands.find({noun, verb}); - if (i == m_commands.end()) { - if (verb.empty()) { - NDN_LOG_TRACE("fallback to noun=" << noun << " verb=list"); - i = m_commands.find({noun, "list"}); - } - else { - // help, exit, quit commands - NDN_LOG_TRACE("fallback to noun=" << noun << " verb="); - i = m_commands.find({noun, ""}); - } - nameLen = std::min(1, tokens.size()); - } - if (i == m_commands.end() || (i->second->modes & static_cast(mode)) == 0) { BOOST_THROW_EXCEPTION(NoSuchCommandError(noun, verb)); } @@ -139,7 +125,8 @@ CommandParser::parse(const std::vector& tokens, ParseMode mode) con const CommandDefinition& def = i->second->def; NDN_LOG_TRACE("found command noun=" << def.getNoun() << " verb=" << def.getVerb()); - return std::make_tuple(def.getNoun(), def.getVerb(), def.parse(tokens, nameLen), i->second->execute); + size_t nConsumed = std::min(2, tokens.size()); + return std::make_tuple(def.getNoun(), def.getVerb(), def.parse(tokens, nConsumed), i->second->execute); } } // namespace nfdc diff --git a/tools/nfdc/face-module.cpp b/tools/nfdc/face-module.cpp index 560b2233..93a6563c 100644 --- a/tools/nfdc/face-module.cpp +++ b/tools/nfdc/face-module.cpp @@ -40,6 +40,7 @@ FaceModule::registerCommands(CommandParser& parser) .addArg("local", ArgValueType::FACE_URI, Required::NO, Positional::NO) .addArg("scheme", ArgValueType::STRING, Required::NO, Positional::NO, "scheme"); parser.addCommand(defFaceList, &FaceModule::list); + parser.addAlias("face", "list", ""); CommandDefinition defFaceShow("face", "show"); defFaceShow diff --git a/tools/nfdc/rib-module.cpp b/tools/nfdc/rib-module.cpp index f9d888f9..a5a24544 100644 --- a/tools/nfdc/rib-module.cpp +++ b/tools/nfdc/rib-module.cpp @@ -40,6 +40,7 @@ RibModule::registerCommands(CommandParser& parser) .addArg("nexthop", ArgValueType::FACE_ID_OR_URI, Required::NO, Positional::YES) .addArg("origin", ArgValueType::ROUTE_ORIGIN, Required::NO, Positional::NO); parser.addCommand(defRouteList, &RibModule::list); + parser.addAlias("route", "list", ""); CommandDefinition defRouteShow("route", "show"); defRouteShow diff --git a/tools/nfdc/status.cpp b/tools/nfdc/status.cpp index 5365fbb0..a47d12b8 100644 --- a/tools/nfdc/status.cpp +++ b/tools/nfdc/status.cpp @@ -129,22 +129,25 @@ registerStatusCommands(CommandParser& parser) defStatusShow .setTitle("print general status"); parser.addCommand(defStatusShow, bind(&reportStatusSingleSection, _1, &StatusReportOptions::wantForwarderGeneral)); - parser.addAlias("status", "show", "list"); + parser.addAlias("status", "show", ""); CommandDefinition defChannelList("channel", "list"); defChannelList .setTitle("print channel list"); parser.addCommand(defChannelList, bind(&reportStatusSingleSection, _1, &StatusReportOptions::wantChannels)); + parser.addAlias("channel", "list", ""); CommandDefinition defFibList("fib", "list"); defFibList .setTitle("print FIB entries"); parser.addCommand(defFibList, bind(&reportStatusSingleSection, _1, &StatusReportOptions::wantFib)); + parser.addAlias("fib", "list", ""); CommandDefinition defCsInfo("cs", "info"); defCsInfo .setTitle("print CS information"); parser.addCommand(defCsInfo, bind(&reportStatusSingleSection, _1, &StatusReportOptions::wantCs)); + parser.addAlias("cs", "info", ""); } } // namespace nfdc diff --git a/tools/nfdc/strategy-choice-module.cpp b/tools/nfdc/strategy-choice-module.cpp index 9e0031f3..5f81f7ac 100644 --- a/tools/nfdc/strategy-choice-module.cpp +++ b/tools/nfdc/strategy-choice-module.cpp @@ -1,6 +1,6 @@ /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ -/** - * Copyright (c) 2014-2017, Regents of the University of California, +/* + * Copyright (c) 2014-2018, Regents of the University of California, * Arizona Board of Regents, * Colorado State University, * University Pierre & Marie Curie, Sorbonne University, @@ -37,6 +37,7 @@ StrategyChoiceModule::registerCommands(CommandParser& parser) defStrategyList .setTitle("print strategy choices"); parser.addCommand(defStrategyList, &StrategyChoiceModule::list); + parser.addAlias("strategy", "list", ""); CommandDefinition defStrategyShow("strategy", "show"); defStrategyShow