aboutsummaryrefslogtreecommitdiff
path: root/gcc/gcc.c
diff options
context:
space:
mode:
authorDavid Malcolm <dmalcolm@redhat.com>2015-11-13 01:59:03 +0000
committerDavid Malcolm <dmalcolm@gcc.gnu.org>2015-11-13 01:59:03 +0000
commit93ebf1fdbe35eadc5e54934061a7a4d7bcdc8262 (patch)
tree03490dac15713b742586dd8e47220bc1bc5db3a3 /gcc/gcc.c
parent277fe616911ac1ce91e9f1178d648303b4a26940 (diff)
downloadgcc-93ebf1fdbe35eadc5e54934061a7a4d7bcdc8262.zip
gcc-93ebf1fdbe35eadc5e54934061a7a4d7bcdc8262.tar.gz
gcc-93ebf1fdbe35eadc5e54934061a7a4d7bcdc8262.tar.bz2
PR driver/67613 - spell suggestions for misspelled command line options
gcc/ChangeLog: PR driver/67613 * Makefile.in (GCC_OBJS): Add spellcheck.o. (OBJS): Add spellcheck-tree.o. * gcc.c: Include "spellcheck.h". (suggest_option): New function. (driver::handle_unrecognized_options): Call suggest_option to provide a hint about misspelled options. * spellcheck.c: Update file comment. (levenshtein_distance): Convert 4-param implementation from static to extern scope. Remove note about unit tests from leading comment for const char * implementation. Move tree implementation to... * spellcheck-tree.c: New file. * spellcheck.h (levenshtein_distance): Add 4-param decl. gcc/testsuite/ChangeLog: PR driver/67613 * gcc/testsuite/gcc.dg/spellcheck-options-1.c: New file. * gcc/testsuite/gcc.dg/spellcheck-options-2.c: New file. From-SVN: r230285
Diffstat (limited to 'gcc/gcc.c')
-rw-r--r--gcc/gcc.c51
1 files changed, 50 insertions, 1 deletions
diff --git a/gcc/gcc.c b/gcc/gcc.c
index 87d1979..6fceca2 100644
--- a/gcc/gcc.c
+++ b/gcc/gcc.c
@@ -42,6 +42,7 @@ compilation is specified by a string called a "spec". */
#include "opts.h"
#include "params.h"
#include "filenames.h"
+#include "spellcheck.h"
@@ -7601,6 +7602,45 @@ driver::maybe_putenv_OFFLOAD_TARGETS () const
offload_targets = NULL;
}
+/* Helper function for driver::handle_unrecognized_options.
+
+ Given an unrecognized option BAD_OPT (without the leading dash),
+ locate the closest reasonable matching option (again, without the
+ leading dash), or NULL. */
+
+static const char *
+suggest_option (const char *bad_opt)
+{
+ const cl_option *best_option = NULL;
+ edit_distance_t best_distance = MAX_EDIT_DISTANCE;
+
+ for (unsigned int i = 0; i < cl_options_count; i++)
+ {
+ edit_distance_t dist = levenshtein_distance (bad_opt,
+ cl_options[i].opt_text + 1);
+ if (dist < best_distance)
+ {
+ best_distance = dist;
+ best_option = &cl_options[i];
+ }
+ }
+
+ if (!best_option)
+ return NULL;
+
+ /* If more than half of the letters were misspelled, the suggestion is
+ likely to be meaningless. */
+ if (best_option)
+ {
+ unsigned int cutoff = MAX (strlen (bad_opt),
+ strlen (best_option->opt_text + 1)) / 2;
+ if (best_distance > cutoff)
+ return NULL;
+ }
+
+ return best_option->opt_text + 1;
+}
+
/* Reject switches that no pass was interested in. */
void
@@ -7608,7 +7648,16 @@ driver::handle_unrecognized_options () const
{
for (size_t i = 0; (int) i < n_switches; i++)
if (! switches[i].validated)
- error ("unrecognized command line option %<-%s%>", switches[i].part1);
+ {
+ const char *hint = suggest_option (switches[i].part1);
+ if (hint)
+ error ("unrecognized command line option %<-%s%>;"
+ " did you mean %<-%s%>?",
+ switches[i].part1, hint);
+ else
+ error ("unrecognized command line option %<-%s%>",
+ switches[i].part1);
+ }
}
/* Handle the various -print-* options, returning 0 if the driver