From a3192a1113f729da9a960b82dd7867c4969930c4 Mon Sep 17 00:00:00 2001 From: Martchus Date: Wed, 29 Nov 2017 22:52:50 +0100 Subject: [PATCH] Fix parsing top-level argument after abbreviation --- application/argumentparser.cpp | 10 +++++++--- tests/argumentparsertests.cpp | 14 +++++++++++++- 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/application/argumentparser.cpp b/application/argumentparser.cpp index 042c6cd..87b60ca 100644 --- a/application/argumentparser.cpp +++ b/application/argumentparser.cpp @@ -185,10 +185,14 @@ void ArgumentReader::read(ArgumentVector &args) argDenotation = nullptr; break; } else { - // further abbreviations follow -> don't increment argv, keep processing outstanding chars of argDenotation + // further abbreviations follow -> remember current arg value + const char *const *currentArgValue = argv; + // don't increment argv, keep processing outstanding chars of argDenotation read(lastArg->m_subArgs); - // stop further processing if denotation has been consumed - if (!argDenotation) { + + // stop further processing if the denotation has been consumed or even the next value has already been loaded + if (!argDenotation || currentArgValue != argv) { + argDenotation = nullptr; break; } } diff --git a/tests/argumentparsertests.cpp b/tests/argumentparsertests.cpp index eb7965b..b4ec2b9 100644 --- a/tests/argumentparsertests.cpp +++ b/tests/argumentparsertests.cpp @@ -125,7 +125,8 @@ void ArgumentParserTests::testParsing() Argument displayTagInfoArg("get", 'p', "displays the values of all specified tag fields (displays all fields if none specified)"); displayTagInfoArg.setDenotesOperation(true); displayTagInfoArg.setSubArguments({ &fieldsArg, &filesArg, &verboseArg, ¬AlbumArg }); - parser.setMainArguments({ &qtConfigArgs.qtWidgetsGuiArg(), &printFieldNamesArg, &displayTagInfoArg, &displayFileInfoArg, &helpArg }); + NoColorArgument noColorArg; + parser.setMainArguments({ &qtConfigArgs.qtWidgetsGuiArg(), &printFieldNamesArg, &displayTagInfoArg, &displayFileInfoArg, &helpArg, &noColorArg }); // error about uncombinable arguments const char *argv[] = { "tageditor", "get", "album", "title", "diskpos", "-f", "somefile" }; @@ -313,6 +314,17 @@ void ArgumentParserTests::testParsing() CPPUNIT_ASSERT_EQUAL(1_st, fileArg.values(0).size()); CPPUNIT_ASSERT(!strcmp(fileArg.values(0).front(), "test")); + // specifying top-level argument after abbreviation + const char *argv17[] = { "tageditor", "-if=test-v", "--no-color" }; + parser.resetArgs(); + parser.parseArgs(3, argv17); + CPPUNIT_ASSERT(!filesArg.isPresent()); + CPPUNIT_ASSERT(fileArg.isPresent()); + CPPUNIT_ASSERT(!verboseArg.isPresent()); + CPPUNIT_ASSERT(noColorArg.isPresent()); + CPPUNIT_ASSERT_EQUAL(1_st, fileArg.values(0).size()); + CPPUNIT_ASSERT_EQUAL("test-v"s, string(fileArg.values(0).front())); + // default argument const char *argv8[] = { "tageditor" }; parser.resetArgs();