diff --git a/lib/utils/mu-command-parser.cc b/lib/utils/mu-command-parser.cc index 719ed393..7c4aa4a9 100644 --- a/lib/utils/mu-command-parser.cc +++ b/lib/utils/mu-command-parser.cc @@ -82,6 +82,13 @@ Command::invoke(const Command::CommandMap& cmap, const Node& call) " but got " + to_string(param_it->type)); } + // all passed parameters must be known + for (size_t i = 1; i < params.size(); i += 2) { + if (std::none_of(cinfo.args.begin(), cinfo.args.end(), + [&](auto&& arg) {return params[i].value == ":" + arg.first;})) + throw command_error("unknown parameter '" + params[i].value + "'"); + } + if (cinfo.handler) cinfo.handler(params); } diff --git a/lib/utils/test-command-parser.cc b/lib/utils/test-command-parser.cc index fad90a48..f18e6425 100644 --- a/lib/utils/test-command-parser.cc +++ b/lib/utils/test-command-parser.cc @@ -63,9 +63,11 @@ static void test_command() { using namespace Command; + allow_warnings(); CommandMap cmap; + cmap.emplace("my-command", CommandInfo{ ArgMap{ {"param1", ArgInfo{Sexp::Type::String, true, "some string" }}, @@ -77,13 +79,15 @@ test_command() g_assert_true(call(cmap, "(my-command :param1 \"hello\")")); g_assert_true(call(cmap, "(my-command :param1 \"hello\" :param2 123)")); - g_assert_true(call(cmap, "(my-command :param1 \"hello\" :param2 123 :param3 xxx)")); + + g_assert_false(call(cmap, "(my-command :param1 \"hello\" :param2 123 :param3 xxx)")); } static void test_command2() { using namespace Command; + allow_warnings(); CommandMap cmap; cmap.emplace("bla", @@ -95,7 +99,8 @@ test_command2() [&](const auto& params){}}); - g_assert_true (call(cmap, "(bla :foo nil :bla nil)")); + g_assert_true (call(cmap, "(bla :foo nil)")); + g_assert_false (call(cmap, "(bla :foo nil :bla nil)")); }