Mercurial > hg > truffle
comparison src/share/vm/runtime/globals.cpp @ 11070:6e3634222155
8017611: Auto corrector for mistyped vm options
Summary: The auto corrector for mistyped vm options fuzzy-matches existing flags based on string similarity (Dice's coefficient).
Reviewed-by: kvn, dsamersoff, hseigel, johnc
author | tamao |
---|---|
date | Fri, 28 Jun 2013 20:18:04 -0700 |
parents | b3cd8b58b798 |
children | 6b0fd0964b87 f98f5d48f511 |
comparison
equal
deleted
inserted
replaced
11069:5ea20b3bd249 | 11070:6e3634222155 |
---|---|
274 }; | 274 }; |
275 | 275 |
276 Flag* Flag::flags = flagTable; | 276 Flag* Flag::flags = flagTable; |
277 size_t Flag::numFlags = (sizeof(flagTable) / sizeof(Flag)); | 277 size_t Flag::numFlags = (sizeof(flagTable) / sizeof(Flag)); |
278 | 278 |
279 inline bool str_equal(const char* s, char* q, size_t len) { | 279 inline bool str_equal(const char* s, const char* q, size_t len) { |
280 // s is null terminated, q is not! | 280 // s is null terminated, q is not! |
281 if (strlen(s) != (unsigned int) len) return false; | 281 if (strlen(s) != (unsigned int) len) return false; |
282 return strncmp(s, q, len) == 0; | 282 return strncmp(s, q, len) == 0; |
283 } | 283 } |
284 | 284 |
285 // Search the flag table for a named flag | 285 // Search the flag table for a named flag |
286 Flag* Flag::find_flag(char* name, size_t length, bool allow_locked) { | 286 Flag* Flag::find_flag(const char* name, size_t length, bool allow_locked) { |
287 for (Flag* current = &flagTable[0]; current->name != NULL; current++) { | 287 for (Flag* current = &flagTable[0]; current->name != NULL; current++) { |
288 if (str_equal(current->name, name, length)) { | 288 if (str_equal(current->name, name, length)) { |
289 // Found a matching entry. Report locked flags only if allowed. | 289 // Found a matching entry. Report locked flags only if allowed. |
290 if (!(current->is_unlocked() || current->is_unlocker())) { | 290 if (!(current->is_unlocked() || current->is_unlocker())) { |
291 if (!allow_locked) { | 291 if (!allow_locked) { |
299 } | 299 } |
300 // Flag name is not in the flag table | 300 // Flag name is not in the flag table |
301 return NULL; | 301 return NULL; |
302 } | 302 } |
303 | 303 |
304 // Compute string similarity based on Dice's coefficient | |
305 static float str_similar(const char* str1, const char* str2, size_t len2) { | |
306 int len1 = (int) strlen(str1); | |
307 int total = len1 + (int) len2; | |
308 | |
309 int hit = 0; | |
310 | |
311 for (int i = 0; i < len1 -1; ++i) { | |
312 for (int j = 0; j < (int) len2 -1; ++j) { | |
313 if ((str1[i] == str2[j]) && (str1[i+1] == str2[j+1])) { | |
314 ++hit; | |
315 break; | |
316 } | |
317 } | |
318 } | |
319 | |
320 return 2.0f * (float) hit / (float) total; | |
321 } | |
322 | |
323 Flag* Flag::fuzzy_match(const char* name, size_t length, bool allow_locked) { | |
324 float VMOptionsFuzzyMatchSimilarity = 0.7f; | |
325 Flag* match = NULL; | |
326 float score; | |
327 float max_score = -1; | |
328 | |
329 for (Flag* current = &flagTable[0]; current->name != NULL; current++) { | |
330 score = str_similar(current->name, name, length); | |
331 if (score > max_score) { | |
332 max_score = score; | |
333 match = current; | |
334 } | |
335 } | |
336 | |
337 if (!(match->is_unlocked() || match->is_unlocker())) { | |
338 if (!allow_locked) { | |
339 return NULL; | |
340 } | |
341 } | |
342 | |
343 if (max_score < VMOptionsFuzzyMatchSimilarity) { | |
344 return NULL; | |
345 } | |
346 | |
347 return match; | |
348 } | |
349 | |
304 // Returns the address of the index'th element | 350 // Returns the address of the index'th element |
305 static Flag* address_of_flag(CommandLineFlagWithType flag) { | 351 static Flag* address_of_flag(CommandLineFlagWithType flag) { |
306 assert((size_t)flag < Flag::numFlags, "bad command line flag index"); | 352 assert((size_t)flag < Flag::numFlags, "bad command line flag index"); |
307 return &Flag::flags[flag]; | 353 return &Flag::flags[flag]; |
308 } | 354 } |