Another use of spellcheck.{c|h}, this time for --param. Successfully bootstrapped®retested on x86_64-pc-linux-gnu; adds 4 PASS results to gcc.sum.
OK for trunk? gcc/ChangeLog: * opts.c (handle_param): Use find_param_fuzzy to offer suggestions for misspelled param names. * params.c: Include spellcheck.h. (find_param_fuzzy): New function. * params.h (find_param_fuzzy): New prototype. * spellcheck.c (struct edit_distance_traits<const char *>): Move to... * spellcheck.h (struct edit_distance_traits<const char *>): ...here. gcc/testsuite/ChangeLog: * gcc.dg/spellcheck-params.c: New testcase. * gcc.dg/spellcheck-params-2.c: New testcase. --- gcc/opts.c | 9 ++++++++- gcc/params.c | 14 ++++++++++++++ gcc/params.h | 1 + gcc/spellcheck.c | 18 ------------------ gcc/spellcheck.h | 18 ++++++++++++++++++ gcc/testsuite/gcc.dg/spellcheck-params-2.c | 4 ++++ gcc/testsuite/gcc.dg/spellcheck-params.c | 4 ++++ 7 files changed, 49 insertions(+), 19 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/spellcheck-params-2.c create mode 100644 gcc/testsuite/gcc.dg/spellcheck-params.c diff --git a/gcc/opts.c b/gcc/opts.c index 7406210..f09c520 100644 --- a/gcc/opts.c +++ b/gcc/opts.c @@ -2228,7 +2228,14 @@ handle_param (struct gcc_options *opts, struct gcc_options *opts_set, enum compiler_param index; if (!find_param (arg, &index)) - error_at (loc, "invalid --param name %qs", arg); + { + const char *suggestion = find_param_fuzzy (arg); + if (suggestion) + error_at (loc, "invalid --param name %qs; did you mean %qs?", + arg, suggestion); + else + error_at (loc, "invalid --param name %qs", arg); + } else { if (!param_string_value_p (index, equal + 1, &value)) diff --git a/gcc/params.c b/gcc/params.c index 41660b4..1b5000b 100644 --- a/gcc/params.c +++ b/gcc/params.c @@ -25,6 +25,7 @@ along with GCC; see the file COPYING3. If not see #include "params.h" #include "params-enum.h" #include "diagnostic-core.h" +#include "spellcheck.h" /* An array containing the compiler parameters and their current values. */ @@ -142,6 +143,19 @@ find_param (const char *name, enum compiler_param *index) return false; } +/* Look for the closest match for NAME in the parameter table, returning it + if it is a reasonable suggestion for a misspelling. Return NULL + otherwise. */ + +const char * +find_param_fuzzy (const char *name) +{ + best_match <const char *, const char *> bm (name); + for (size_t i = 0; i < num_compiler_params; ++i) + bm.consider (compiler_params[i].option); + return bm.get_best_meaningful_candidate (); +} + /* Return true if param with entry index INDEX should be defined using strings. If so, return the value corresponding to VALUE_NAME in *VALUE_P. */ diff --git a/gcc/params.h b/gcc/params.h index 7221ab6..97c8d56 100644 --- a/gcc/params.h +++ b/gcc/params.h @@ -89,6 +89,7 @@ enum compiler_param }; extern bool find_param (const char *, enum compiler_param *); +extern const char *find_param_fuzzy (const char *name); extern bool param_string_value_p (enum compiler_param, const char *, int *); /* The value of the parameter given by ENUM. Not an lvalue. */ diff --git a/gcc/spellcheck.c b/gcc/spellcheck.c index 2648f3a..b37b1e4 100644 --- a/gcc/spellcheck.c +++ b/gcc/spellcheck.c @@ -121,24 +121,6 @@ levenshtein_distance (const char *s, const char *t) return levenshtein_distance (s, strlen (s), t, strlen (t)); } -/* Specialization of edit_distance_traits for C-style strings. */ - -template <> -struct edit_distance_traits<const char *> -{ - static size_t get_length (const char *str) - { - gcc_assert (str); - return strlen (str); - } - - static const char *get_string (const char *str) - { - gcc_assert (str); - return str; - } -}; - /* Given TARGET, a non-NULL string, and CANDIDATES, a non-NULL ptr to an autovec of non-NULL strings, determine which element within CANDIDATES has the lowest edit distance to TARGET. If there are diff --git a/gcc/spellcheck.h b/gcc/spellcheck.h index 035f4ac..b48cfbc 100644 --- a/gcc/spellcheck.h +++ b/gcc/spellcheck.h @@ -48,6 +48,24 @@ find_closest_string (const char *target, template <typename TYPE> struct edit_distance_traits {}; +/* Specialization of edit_distance_traits for C-style strings. */ + +template <> +struct edit_distance_traits<const char *> +{ + static size_t get_length (const char *str) + { + gcc_assert (str); + return strlen (str); + } + + static const char *get_string (const char *str) + { + gcc_assert (str); + return str; + } +}; + /* A type for use when determining the best match against a string, expressed as a template so that we can match against various string-like types (const char *, frontend identifiers, and preprocessor diff --git a/gcc/testsuite/gcc.dg/spellcheck-params-2.c b/gcc/testsuite/gcc.dg/spellcheck-params-2.c new file mode 100644 index 0000000..27e293f --- /dev/null +++ b/gcc/testsuite/gcc.dg/spellcheck-params-2.c @@ -0,0 +1,4 @@ +/* { dg-do compile } */ +/* { dg-options "--param does-not-resemble-anything=42" } */ +/* { dg-error "invalid --param name .does-not-resemble-anything." "" { target *-*-* } 0 } */ + diff --git a/gcc/testsuite/gcc.dg/spellcheck-params.c b/gcc/testsuite/gcc.dg/spellcheck-params.c new file mode 100644 index 0000000..1bb7bca --- /dev/null +++ b/gcc/testsuite/gcc.dg/spellcheck-params.c @@ -0,0 +1,4 @@ +/* { dg-do compile } */ +/* { dg-options "--param max-early-inliner-iteration=3" } */ +/* { dg-error "invalid --param name .max-early-inliner-iteration.; did you mean .max-early-inliner-iterations.?" "" { target *-*-* } 0 } */ + -- 1.8.5.3