From 24720bbbc1def89bfd8a76bf8a203cf3d90ff955 Mon Sep 17 00:00:00 2001 From: Martchus Date: Fri, 11 May 2018 15:51:30 +0200 Subject: [PATCH] Fix passing cursor position to findSuggestions() --- application/argumentparser.cpp | 21 ++++++++++++++------- tests/argumentparsertests.cpp | 10 ++++++++++ 2 files changed, 24 insertions(+), 7 deletions(-) diff --git a/application/argumentparser.cpp b/application/argumentparser.cpp index bf393bd..3f7a6cc 100644 --- a/application/argumentparser.cpp +++ b/application/argumentparser.cpp @@ -938,9 +938,11 @@ void ArgumentParser::readArgs(int argc, const char *const *argv) return; } - // if the first argument (after executable name) is "--bash-completion-for", bash completion for the following arguments is requested - bool completionMode = !strcmp(*++argv, "--bash-completion-for"); - unsigned int currentWordIndex; + // check for completion mode: if first arg (after executable name) is "--bash-completion-for", bash completion for the following arguments is requested + const bool completionMode = !strcmp(*++argv, "--bash-completion-for"); + + // determine the index of the current word for completion and the number of arguments to be passed to ArgumentReader + unsigned int currentWordIndex, argcForReader; if (completionMode) { // the first argument after "--bash-completion-for" is the index of the current word try { @@ -951,21 +953,26 @@ void ArgumentParser::readArgs(int argc, const char *const *argv) } catch (const ConversionException &) { currentWordIndex = static_cast(argc - 1); } + argcForReader = min(static_cast(argc), currentWordIndex + 1); + } else { + argcForReader = static_cast(argc); } // read specified arguments - ArgumentReader reader(*this, argv, - argv + (completionMode ? min(static_cast(argc), currentWordIndex + 1) : static_cast(argc)), completionMode); + ArgumentReader reader(*this, argv, argv + argcForReader, completionMode); const bool allArgsProcessed(reader.read()); NoColorArgument::apply(); + + // fail when not all arguments could be processed, except when in completion mode if (!completionMode && !allArgsProcessed) { - const auto suggestions(findSuggestions(argc, argv, currentWordIndex, reader)); + const auto suggestions(findSuggestions(argc, argv, static_cast(argc - 1), reader)); throw Failure(argsToString("The specified argument \"", *reader.argv, "\" is unknown.", suggestions)); } + // print Bash completion and prevent the applicaton to continue with the regular execution if (completionMode) { printBashCompletion(argc, argv, currentWordIndex, reader); - exitFunction(0); // prevent the applicaton to continue with the regular execution + exitFunction(0); } } diff --git a/tests/argumentparsertests.cpp b/tests/argumentparsertests.cpp index 7da48dc..5be5949 100644 --- a/tests/argumentparsertests.cpp +++ b/tests/argumentparsertests.cpp @@ -199,6 +199,16 @@ void ArgumentParserTests::testParsing() CPPUNIT_ASSERT_EQUAL("The specified argument \"album\" is unknown.\nDid you mean get or help?"s, string(e.what())); } + // error about unknown argument: mistake in final argument + const char *argv18[] = { "tageditor", "get", "album", "title", "diskpos", "--verbose", "--fi" }; + try { + parser.resetArgs(); + parser.parseArgs(7, argv18); + CPPUNIT_FAIL("Exception expected."); + } catch (const Failure &e) { + CPPUNIT_ASSERT_EQUAL("The specified argument \"--fi\" is unknown.\nDid you mean files or no-color?"s, string(e.what())); + } + // warning about unknown argument parser.setUnknownArgumentBehavior(UnknownArgumentBehavior::Warn); // redirect stderr to check whether warnings are printed correctly