Skip to content

Commit

Permalink
Add driver-based boolean/non-boolean hosted option mismatch detection
Browse files Browse the repository at this point in the history
  • Loading branch information
olpaw committed Jan 21, 2025
1 parent 1c9f5c6 commit a2987bf
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 15 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,8 @@ public class CommonOptionParser {
public static final String HOSTED_OPTION_PREFIX = "-H:";
public static final String RUNTIME_OPTION_PREFIX = "-R:";
public static final char PLUS_MINUS_BOOLEAN_OPTION_PREFIX = '\u00b1';
public static final String MISMATCH_BOOLEAN_OPTION = "Boolean option %s must have " + PLUS_MINUS_BOOLEAN_OPTION_PREFIX + " prefix. Use '" + PLUS_MINUS_BOOLEAN_OPTION_PREFIX + "%s' format.";
public static final String MISMATCH_NON_BOOLEAN_OPTION = "Non-boolean option %s can not use " + PLUS_MINUS_BOOLEAN_OPTION_PREFIX + " prefix. Use '%s=<value>' format.";

public static final int PRINT_OPTION_INDENTATION = 2;
public static final int PRINT_OPTION_WIDTH = 45;
Expand Down Expand Up @@ -244,7 +246,7 @@ public static OptionParseResult parseOption(EconomicMap<String, OptionDescriptor

if (value == null) {
if (optionType == Boolean.class && booleanOptionFormat == BooleanOptionFormat.PLUS_MINUS) {
return OptionParseResult.error("Boolean option " + current + " must have +/- prefix");
return OptionParseResult.error(MISMATCH_BOOLEAN_OPTION.formatted(current, current.name));
}
if (valueString == null) {
return OptionParseResult.error("Missing value for option " + current);
Expand All @@ -259,7 +261,7 @@ public static OptionParseResult parseOption(EconomicMap<String, OptionDescriptor
}
} else {
if (optionType != Boolean.class) {
return OptionParseResult.error("Non-boolean option " + current + " can not use +/- prefix. Use '" + current.name + "=<value>' format");
return OptionParseResult.error(MISMATCH_NON_BOOLEAN_OPTION.formatted(current, current.name));
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -355,17 +355,8 @@ private void validateHostedOption(String hostedOptionArg, String argumentOrigin)
if (info == null) {
List<String> matches = new ArrayList<>();
OptionsParser.collectFuzzyMatches(() -> allOptionNames.keySet().iterator(), optionName, matches, Function.identity());
StringBuilder msg = new StringBuilder();
msg.append("Unrecognized option '").append(NativeImage.oH);
if (booleanPrefix != 0) {
msg.append(booleanPrefix);
}
msg.append(optionName);
if (booleanPrefix == 0) {
msg.append("=...");
}
OptionOrigin optionOrigin = OptionOrigin.from(argumentOrigin);
msg.append("' from ").append(optionOrigin).append('.');
StringBuilder msg = new StringBuilder("Unrecognized option ");
msg.append(optionDescription(optionName, booleanPrefix, argumentOrigin)).append('.');
if (!matches.isEmpty()) {
msg.append(" Did you mean one of these:");
for (var match : matches) {
Expand All @@ -385,11 +376,32 @@ private void validateHostedOption(String hostedOptionArg, String argumentOrigin)
msg.append(" Use '--expert-options' (see also '--help-extra') to list all available options.");
throw NativeImage.showError(msg.toString());
}
if ((booleanPrefix != 0) != info.isBoolean()) {
var optionDescription = optionDescription(optionName, booleanPrefix, argumentOrigin);
if (info.isBoolean()) {
throw NativeImage.showError(CommonOptionParser.MISMATCH_BOOLEAN_OPTION.formatted(optionDescription, optionName));
} else {
throw NativeImage.showError(CommonOptionParser.MISMATCH_NON_BOOLEAN_OPTION.formatted(optionDescription, optionName));
}
}
if (numberOfActiveUnlockExperimentalVMOptions == 0 && !info.isStable()) {
illegalExperimentalOptions.add(hostedOptionArg);
}
}

private static String optionDescription(String optionName, char booleanPrefix, String argumentOrigin) {
var result = new StringBuilder("'" + NativeImage.oH);
if (booleanPrefix != 0) {
result.append(booleanPrefix);
}
result.append(optionName);
if (booleanPrefix == 0) {
result.append("=...");
}
result.append("' from ").append(OptionOrigin.from(argumentOrigin));
return result.toString();
}

String translateOption(ArgumentQueue argQueue) {
OptionInfo option = null;
boolean whitespaceSeparated = false;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1059,12 +1059,12 @@ private static String injectHostedOptionOrigin(String option, String origin) {
char boolPrefix = option.length() > oH.length() ? option.charAt(oH.length()) : 0;
if (boolPrefix == '-' || boolPrefix == '+') {
if (eqIndex != -1) {
showError("Malformed boolean native-image hosted-option '" + option + "' (boolean option with extraneous '=') from " + OptionOrigin.from(origin));
showError("Malformed boolean native-image hosted-option '" + option + "' (boolean option with extraneous '=') from " + OptionOrigin.from(origin) + ".");
}
return option + optionOriginSeparator + origin;
} else {
if (eqIndex == -1) {
showError("Malformed native-image hosted-option '" + option + "' ('=' missing after option name) from " + OptionOrigin.from(origin));
showError("Malformed native-image hosted-option '" + option + "' ('=' missing after option name) from " + OptionOrigin.from(origin) + ".");
}
String front = option.substring(0, eqIndex);
String back = option.substring(eqIndex);
Expand Down

0 comments on commit a2987bf

Please # to comment.