comparison graal/com.oracle.jvmci.options/src/com/oracle/jvmci/options/OptionUtils.java @ 21562:47bebae7454f

Merge.
author Doug Simon <doug.simon@oracle.com>
date Thu, 28 May 2015 21:58:33 +0200
parents graal/com.oracle.graal.options/src/com/oracle/graal/options/OptionUtils.java@cecb4e39521c graal/com.oracle.graal.options/src/com/oracle/graal/options/OptionUtils.java@b1530a6cce8c
children
comparison
equal deleted inserted replaced
21561:ce2113326bc8 21562:47bebae7454f
32 32
33 /** 33 /**
34 * Parses a given option value specification. 34 * Parses a given option value specification.
35 * 35 *
36 * @param option the specification of an option and its value 36 * @param option the specification of an option and its value
37 * @param setter the object to notify of the parsed option and value. If null, the 37 * @param setter the object to notify of the parsed option and value.
38 * {@link OptionValue#setValue(Object)} method of the specified option is called
39 * instead.
40 */ 38 */
41 public static boolean parseOption(SortedMap<String, OptionDescriptor> options, String option, String prefix, OptionConsumer setter) { 39 public static void parseOption(String option, OptionConsumer setter) {
40 SortedMap<String, OptionDescriptor> options = OptionsLoader.options;
41 Objects.requireNonNull(setter);
42 if (option.length() == 0) { 42 if (option.length() == 0) {
43 return false; 43 return;
44 } 44 }
45 45
46 Object value = null; 46 Object value = null;
47 String optionName = null; 47 String optionName = null;
48 String valueString = null; 48 String valueString = null;
49
50 if (option.equals("+PrintFlags")) {
51 printFlags(options, prefix);
52 return true;
53 }
54 49
55 char first = option.charAt(0); 50 char first = option.charAt(0);
56 if (first == '+' || first == '-') { 51 if (first == '+' || first == '-') {
57 optionName = option.substring(1); 52 optionName = option.substring(1);
58 value = (first == '+'); 53 value = (first == '+');
67 } 62 }
68 } 63 }
69 64
70 OptionDescriptor desc = options.get(optionName); 65 OptionDescriptor desc = options.get(optionName);
71 if (desc == null) { 66 if (desc == null) {
72 printNoMatchMessage(options, optionName, prefix); 67 throw new IllegalArgumentException("Option '" + optionName + "' not found");
73 return false;
74 } 68 }
75 69
76 Class<?> optionType = desc.getType(); 70 Class<?> optionType = desc.getType();
77 71
78 if (value == null) { 72 if (value == null) {
79 if (optionType == Boolean.TYPE || optionType == Boolean.class) { 73 if (optionType == Boolean.TYPE || optionType == Boolean.class) {
80 System.err.println("Value for boolean option '" + optionName + "' must use '" + prefix + "+" + optionName + "' or '" + prefix + "-" + optionName + "' format"); 74 throw new IllegalArgumentException("Boolean option '" + optionName + "' must use +/- prefix");
81 return false;
82 } 75 }
83 76
84 if (valueString == null) { 77 if (valueString == null) {
85 System.err.println("Value for option '" + optionName + "' must use '" + prefix + optionName + "=<value>' format"); 78 throw new IllegalArgumentException("Missing value for non-boolean option '" + optionName + "' must use " + optionName + "=<value> format");
86 return false;
87 } 79 }
88 80
89 if (optionType == Float.class) { 81 if (optionType == Float.class) {
90 value = Float.parseFloat(valueString); 82 value = Float.parseFloat(valueString);
91 } else if (optionType == Double.class) { 83 } else if (optionType == Double.class) {
94 value = Integer.valueOf((int) parseLong(valueString)); 86 value = Integer.valueOf((int) parseLong(valueString));
95 } else if (optionType == Long.class) { 87 } else if (optionType == Long.class) {
96 value = Long.valueOf(parseLong(valueString)); 88 value = Long.valueOf(parseLong(valueString));
97 } else if (optionType == String.class) { 89 } else if (optionType == String.class) {
98 value = valueString; 90 value = valueString;
91 } else {
92 throw new IllegalArgumentException("Wrong value for option '" + optionName + "'");
99 } 93 }
100 } else { 94 } else {
101 if (optionType != Boolean.class) { 95 if (optionType != Boolean.class) {
102 System.err.println("Value for option '" + optionName + "' must use '" + prefix + optionName + "=<value>' format"); 96 throw new IllegalArgumentException("Non-boolean option '" + optionName + "' can not use +/- prefix. Use " + optionName + "=<value> format");
103 return false;
104 } 97 }
105 } 98 }
106 99
107 if (value != null) { 100 setter.set(desc, value);
108 if (setter != null) {
109 setter.set(desc, value);
110 } else {
111 OptionValue<?> optionValue = desc.getOptionValue();
112 optionValue.setValue(value);
113 // System.err.println("Set option " + desc.getName() + " to " + value);
114 }
115 } else {
116 System.err.println("Wrong value \"" + valueString + "\" for option " + optionName);
117 return false;
118 }
119
120 return true;
121 } 101 }
122 102
123 private static long parseLong(String v) { 103 private static long parseLong(String v) {
124 String valueString = v.toLowerCase(); 104 String valueString = v.toLowerCase();
125 long scale = 1; 105 long scale = 1;
137 /* Remove trailing scale character. */ 117 /* Remove trailing scale character. */
138 valueString = valueString.substring(0, valueString.length() - 1); 118 valueString = valueString.substring(0, valueString.length() - 1);
139 } 119 }
140 120
141 return Long.parseLong(valueString) * scale; 121 return Long.parseLong(valueString) * scale;
142 }
143
144 public static void printNoMatchMessage(SortedMap<String, OptionDescriptor> options, String optionName, String prefix) {
145 OptionDescriptor desc = options.get(optionName);
146 if (desc != null) {
147 if (desc.getType() == Boolean.class) {
148 System.err.println("Boolean option " + optionName + " must be prefixed with '+' or '-'");
149 } else {
150 System.err.println(desc.getType().getSimpleName() + " option " + optionName + " must not be prefixed with '+' or '-'");
151 }
152 } else {
153 System.err.println("Could not find option " + optionName + " (use " + prefix + "+PrintFlags to see options)");
154 List<OptionDescriptor> matches = fuzzyMatch(options, optionName);
155 if (!matches.isEmpty()) {
156 System.err.println("Did you mean one of the following?");
157 for (OptionDescriptor match : matches) {
158 boolean isBoolean = match.getType() == Boolean.class;
159 System.err.println(String.format(" %s%s%s", isBoolean ? "(+/-)" : "", match.getName(), isBoolean ? "" : "=<value>"));
160 }
161 }
162 }
163 } 122 }
164 123
165 /** 124 /**
166 * Wraps some given text to one or more lines of a given maximum width. 125 * Wraps some given text to one or more lines of a given maximum width.
167 * 126 *
218 } 177 }
219 } 178 }
220 179
221 System.exit(0); 180 System.exit(0);
222 } 181 }
223
224 /**
225 * Compute string similarity based on Dice's coefficient.
226 *
227 * Ported from str_similar() in globals.cpp.
228 */
229 static float stringSimiliarity(String str1, String str2) {
230 int hit = 0;
231 for (int i = 0; i < str1.length() - 1; ++i) {
232 for (int j = 0; j < str2.length() - 1; ++j) {
233 if ((str1.charAt(i) == str2.charAt(j)) && (str1.charAt(i + 1) == str2.charAt(j + 1))) {
234 ++hit;
235 break;
236 }
237 }
238 }
239 return 2.0f * hit / (str1.length() + str2.length());
240 }
241
242 private static final float FUZZY_MATCH_THRESHOLD = 0.7F;
243
244 /**
245 * Returns the set of options that fuzzy match a given option name.
246 */
247 private static List<OptionDescriptor> fuzzyMatch(SortedMap<String, OptionDescriptor> options, String optionName) {
248 List<OptionDescriptor> matches = new ArrayList<>();
249 for (Map.Entry<String, OptionDescriptor> e : options.entrySet()) {
250 float score = stringSimiliarity(e.getKey(), optionName);
251 if (score >= FUZZY_MATCH_THRESHOLD) {
252 matches.add(e.getValue());
253 }
254 }
255 return matches;
256 }
257 } 182 }