diff --git a/slsDetectorSoftware/include/multiSlsDetectorClient.h b/slsDetectorSoftware/include/multiSlsDetectorClient.h index 63104c3a8..054f7866b 100755 --- a/slsDetectorSoftware/include/multiSlsDetectorClient.h +++ b/slsDetectorSoftware/include/multiSlsDetectorClient.h @@ -27,6 +27,8 @@ class multiSlsDetectorClient { std::ostream &output = std::cout) : action_(action), detPtr(myDetector), os(output) { parser.Parse(argc, argv); + if (parser.isHelp()) + action_ = slsDetectorDefs::HELP_ACTION; runCommand(); } @@ -35,6 +37,7 @@ class multiSlsDetectorClient { std::ostream &output = std::cout) : action_(action), detPtr(myDetector), os(output) { parser.Parse(args); + action_ = slsDetectorDefs::HELP_ACTION; runCommand(); } @@ -108,7 +111,7 @@ class multiSlsDetectorClient { if (action_ != slsDetectorDefs::READOUT_ACTION) { sls::CmdProxy proxy(detPtr); auto cmd = proxy.Call(parser.command(), parser.arguments(), - parser.detector_id()); + parser.detector_id(), action_); if (cmd.empty()) { return; } else { diff --git a/slsSupportLib/include/CmdLineParser.h b/slsSupportLib/include/CmdLineParser.h index 811d88740..44a2200ad 100755 --- a/slsSupportLib/include/CmdLineParser.h +++ b/slsSupportLib/include/CmdLineParser.h @@ -14,6 +14,7 @@ class CmdLineParser { int detector_id() const { return detector_id_; }; int n_arguments() const { return arguments_.size(); } const std::string &command() const { return command_; } + bool isHelp() const{return help_;} void setCommand(std::string cmd){command_ = cmd;} const std::string &executable() const { return executable_; } const std::vector &arguments() const { return arguments_; }; @@ -23,6 +24,7 @@ class CmdLineParser { void DecodeIdAndPosition(const char *c); int multi_id_ = 0; int detector_id_ = -1; + bool help_{false}; std::string command_; std::string executable_; std::vector arguments_; diff --git a/slsSupportLib/include/CmdProxy.h b/slsSupportLib/include/CmdProxy.h index faaa7309c..278c2723f 100644 --- a/slsSupportLib/include/CmdProxy.h +++ b/slsSupportLib/include/CmdProxy.h @@ -10,6 +10,7 @@ #include "logger.h" #include "slsDetectorCommand.h" #include "sls_detector_exceptions.h" +#include "sls_detector_defs.h" #include "string_utils.h" namespace sls { @@ -20,7 +21,8 @@ template class CmdProxy { std::string Call(const std::string &command, const std::vector &arguments, - int detector_id) { + int detector_id, + int action=-1) { cmd = command; args = arguments; det_id = detector_id; @@ -29,7 +31,7 @@ template class CmdProxy { auto it = functions.find(cmd); if (it != functions.end()) { - std::cout << ((*this).*(it->second))(); + std::cout << ((*this).*(it->second))(action); return {}; } else { return cmd; @@ -57,7 +59,7 @@ template class CmdProxy { std::vector args; int det_id{-1}; - using FunctionMap = std::map; + using FunctionMap = std::map; using StringMap = std::map; // Initialize maps for translating name and function @@ -91,7 +93,10 @@ template class CmdProxy { // Mapped functions - std::string ListCommands() { + std::string ListCommands(int action) { + if (action==slsDetectorDefs::HELP_ACTION) + return "list - lists all available commands, list deprecated - list deprecated commands\n"; + if (args.size() == 0) { auto commands = slsDetectorCommand(nullptr).getAllCommands(); for (const auto &it : functions) diff --git a/slsSupportLib/src/CmdLineParser.cpp b/slsSupportLib/src/CmdLineParser.cpp index cc502978d..17394296b 100755 --- a/slsSupportLib/src/CmdLineParser.cpp +++ b/slsSupportLib/src/CmdLineParser.cpp @@ -1,5 +1,6 @@ #include "CmdLineParser.h" +#include "sls_detector_defs.h" #include #include #include @@ -20,22 +21,37 @@ void CmdLineParser::Print() { std::cout << "\n\n"; }; -void CmdLineParser::Parse(int argc, const char * const argv[]) { - executable_ = argv[0]; //first arg is calling binary +void CmdLineParser::Parse(int argc, const char *const argv[]) { + executable_ = argv[0]; // first arg is calling binary if (argc > 1) { - DecodeIdAndPosition(argv[1]); + std::string s = argv[1]; for (int i = 2; i < argc; ++i) { - arguments_.emplace_back(argv[i]); + s += " "; + s += argv[i]; } + Parse(s); } } void CmdLineParser::Parse(const std::string &s) { std::istringstream iss(s); auto it = std::istream_iterator(iss); - command_ = *it++; arguments_ = std::vector(it, std::istream_iterator()); + auto old_size = arguments_.size(); + arguments_.erase(std::remove_if(begin(arguments_), end(arguments_), + [](const std::string &item) { + if (item == "-h" || item == "--help") + return true; + return false; + }), + end(arguments_)); + if (old_size - arguments_.size() > 0) + help_ = true; + if(!arguments_.empty()){ + command_ = arguments_[0]; + arguments_.erase(begin(arguments_)); + } DecodeIdAndPosition(command_.c_str()); } @@ -47,7 +63,7 @@ void CmdLineParser::DecodeIdAndPosition(const char *c) { if (contains_id && contains_pos) { int r = sscanf(c, "%d-%d:%s", &multi_id_, &detector_id_, tmp); if (r != 3) { - throw(std::invalid_argument( + throw(sls::RuntimeError( "Cannot decode client or detector id from: \"" + std::string(c) + "\"\n")); } @@ -55,15 +71,15 @@ void CmdLineParser::DecodeIdAndPosition(const char *c) { } else if (contains_id && !contains_pos) { int r = sscanf(c, "%d-%s", &multi_id_, tmp); if (r != 2) { - throw(std::invalid_argument("Cannot decode client id from: \"" + - std::string(c) + "\"\n")); + throw(sls::RuntimeError("Cannot decode client id from: \"" + + std::string(c) + "\"\n")); } command_ = tmp; } else if (!contains_id && contains_pos) { int r = sscanf(c, "%d:%s", &detector_id_, tmp); if (r != 2) { - throw(std::invalid_argument("Cannot decode detector id from: \"" + - std::string(c) + "\"\n")); + throw(sls::RuntimeError("Cannot decode detector id from: \"" + + std::string(c) + "\"\n")); } command_ = tmp; } else { diff --git a/slsSupportLib/tests/test-CmdLineParser.cpp b/slsSupportLib/tests/test-CmdLineParser.cpp index 5a34e7bd5..4e8ef67e8 100755 --- a/slsSupportLib/tests/test-CmdLineParser.cpp +++ b/slsSupportLib/tests/test-CmdLineParser.cpp @@ -116,12 +116,51 @@ SCENARIO("Parsing a string with the command line parser", "[support]") { } } +SCENARIO("Parsing strings with -h or --help", "[support]") { + GIVEN("A parser") { + CmdLineParser p; + WHEN("Parsing a string with a command and help ") { + std::string s = "-h list"; + + THEN("the command is correct and isHelp is set") { + p.Parse(s); + REQUIRE(p.detector_id() == -1); + REQUIRE(p.multi_id() == 0); + REQUIRE(p.command() == "list"); + REQUIRE(p.isHelp()); + REQUIRE(p.arguments().empty()); + REQUIRE(p.argv().size() == 1); + } + } + WHEN("Parsing a string with -h at a different position"){ + std::string s = "list -h something"; + THEN("its also done right"){ + p.Parse(s); + REQUIRE(p.isHelp()); + REQUIRE(p.command() == "list"); + REQUIRE(p.arguments().size() == 1); + REQUIRE(p.arguments().front() == "something"); + } + } + WHEN("Parsing a string with -help at a different position"){ + std::string s = "list --help something"; + THEN("its also done right"){ + p.Parse(s); + REQUIRE(p.isHelp()); + REQUIRE(p.command() == "list"); + REQUIRE(p.arguments().size() == 1); + REQUIRE(p.arguments().front() == "something"); + } + } + } +} + TEST_CASE("Parse with no arguments results in no command and default id", "[support]") { // build up argc and argv // first argument is the command used to call the binary int argc = 1; - const char* const argv[]{"call"}; + const char *const argv[]{"call"}; CmdLineParser p; p.Parse(argc, argv); @@ -135,7 +174,7 @@ TEST_CASE( "Parse a command without client id and detector id results in default", "[support]") { int argc = 2; - const char*const argv[]{"caller", "vrf"}; + const char *const argv[]{"caller", "vrf"}; CmdLineParser p; p.Parse(argc, argv); @@ -148,7 +187,7 @@ TEST_CASE( TEST_CASE("Parse a command with value but without client or detector id", "[support]") { int argc = 3; - const char* const argv[]{"caller", "vrf", "3000"}; + const char *const argv[]{"caller", "vrf", "3000"}; CmdLineParser p; p.Parse(argc, argv); @@ -161,7 +200,7 @@ TEST_CASE("Parse a command with value but without client or detector id", TEST_CASE("Decodes position") { int argc = 2; - const char*const argv[]{"caller", "7:vrf"}; + const char *const argv[]{"caller", "7:vrf"}; CmdLineParser p; p.Parse(argc, argv); @@ -174,7 +213,7 @@ TEST_CASE("Decodes position") { TEST_CASE("Decodes double digit position", "[support]") { int argc = 2; - const char* const argv[]{"caller", "73:vcmp"}; + const char *const argv[]{"caller", "73:vcmp"}; CmdLineParser p; p.Parse(argc, argv); @@ -186,7 +225,7 @@ TEST_CASE("Decodes double digit position", "[support]") { TEST_CASE("Decodes position and id", "[support]") { int argc = 2; - const char* const argv[]{"caller", "5-8:vrf"}; + const char *const argv[]{"caller", "5-8:vrf"}; CmdLineParser p; p.Parse(argc, argv);