Skip to content

Commit bdb4a09

Browse files
committed
Added support for disabling partial option matching
1 parent 6e7850b commit bdb4a09

1 file changed

Lines changed: 54 additions & 9 deletions

File tree

src/main/java/org/apache/commons/cli/DefaultParser.java

Lines changed: 54 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,24 @@ public class DefaultParser implements CommandLineParser
5353

5454
/** The required options and groups expected to be found when parsing the command line. */
5555
protected List expectedOpts;
56-
56+
57+
/** Flag indicating if partial matching of long options is supported. */
58+
private boolean allowPartialMatching;
59+
60+
/** Creates a new DefaultParser instance with partial matching enabled. */
61+
public DefaultParser() {
62+
this.allowPartialMatching = true;
63+
}
64+
65+
/**
66+
* Create a new DefaultParser instance with the specified partial matching policy.
67+
*
68+
* @param allowPartialMatching if partial matching of long options shall be enabled
69+
*/
70+
public DefaultParser(final boolean allowPartialMatching) {
71+
this.allowPartialMatching = allowPartialMatching;
72+
}
73+
5774
public CommandLine parse(final Options options, final String[] arguments) throws ParseException
5875
{
5976
return parse(options, arguments, null);
@@ -329,7 +346,7 @@ private boolean isLongOption(final String token)
329346
final int pos = token.indexOf("=");
330347
final String t = pos == -1 ? token : token.substring(0, pos);
331348

332-
if (!options.getMatchingOptions(t).isEmpty())
349+
if (!getMatchingLongOptions(t).isEmpty())
333350
{
334351
// long or partial long options (--L, -L, --L=V, -L=V, --l, --l=V)
335352
return true;
@@ -400,18 +417,19 @@ private void handleLongOption(final String token) throws ParseException
400417
*/
401418
private void handleLongOptionWithoutEqual(final String token) throws ParseException
402419
{
403-
final List<String> matchingOpts = options.getMatchingOptions(token);
420+
final List<String> matchingOpts = getMatchingLongOptions(token);
404421
if (matchingOpts.isEmpty())
405422
{
406423
handleUnknownToken(currentToken);
407424
}
408-
else if (matchingOpts.size() > 1)
425+
else if (matchingOpts.size() > 1 && !options.hasLongOption(token))
409426
{
410427
throw new AmbiguousOptionException(token, matchingOpts);
411428
}
412429
else
413430
{
414-
handleOption(options.getOption(matchingOpts.get(0)));
431+
final String key = options.hasLongOption(token) ? token : matchingOpts.get(0);
432+
handleOption(options.getOption(key));
415433
}
416434
}
417435

@@ -433,18 +451,19 @@ private void handleLongOptionWithEqual(final String token) throws ParseException
433451

434452
final String opt = token.substring(0, pos);
435453

436-
final List<String> matchingOpts = options.getMatchingOptions(opt);
454+
final List<String> matchingOpts = getMatchingLongOptions(opt);
437455
if (matchingOpts.isEmpty())
438456
{
439457
handleUnknownToken(currentToken);
440458
}
441-
else if (matchingOpts.size() > 1)
459+
else if (matchingOpts.size() > 1 && !options.hasLongOption(opt))
442460
{
443461
throw new AmbiguousOptionException(opt, matchingOpts);
444462
}
445463
else
446464
{
447-
final Option option = options.getOption(matchingOpts.get(0));
465+
final String key = options.hasLongOption(opt) ? opt : matchingOpts.get(0);
466+
final Option option = options.getOption(key);
448467

449468
if (option.acceptsArg())
450469
{
@@ -503,7 +522,7 @@ else if (pos == -1)
503522
{
504523
handleOption(options.getOption(t));
505524
}
506-
else if (!options.getMatchingOptions(t).isEmpty())
525+
else if (!getMatchingLongOptions(t).isEmpty())
507526
{
508527
// -L or -l
509528
handleLongOptionWithoutEqual(token);
@@ -652,6 +671,32 @@ private void updateRequiredOptions(final Option option) throws AlreadySelectedEx
652671
}
653672
}
654673

674+
/**
675+
* Returns a list of matching option strings for the given token, depending
676+
* on the selected partial matching policy.
677+
*
678+
* @param token the token (may contain leading dashes)
679+
* @return the list of matching option strings or an empty list if no matching option could be found
680+
*/
681+
private List<String> getMatchingLongOptions(final String token)
682+
{
683+
if (allowPartialMatching)
684+
{
685+
return options.getMatchingOptions(token);
686+
}
687+
else
688+
{
689+
List<String> matches = new ArrayList<String>(1);
690+
if (options.hasLongOption(token))
691+
{
692+
Option option = options.getOption(token);
693+
matches.add(option.getLongOpt());
694+
}
695+
696+
return matches;
697+
}
698+
}
699+
655700
/**
656701
* Breaks <code>token</code> into its constituent parts
657702
* using the following algorithm.

0 commit comments

Comments
 (0)