aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog17
-rw-r--r--gcc/Makefile.in3
-rw-r--r--gcc/gcc.c51
-rw-r--r--gcc/spellcheck-tree.c39
-rw-r--r--gcc/spellcheck.c21
-rw-r--r--gcc/spellcheck.h4
-rw-r--r--gcc/testsuite/ChangeLog6
-rw-r--r--gcc/testsuite/gcc.dg/spellcheck-options-1.c4
-rw-r--r--gcc/testsuite/gcc.dg/spellcheck-options-2.c5
9 files changed, 130 insertions, 20 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 1febdcf..0c03eb0 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,5 +1,22 @@
2015-11-13 David Malcolm <dmalcolm@redhat.com>
+ 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.
+
+2015-11-13 David Malcolm <dmalcolm@redhat.com>
+
* Makefile.in (OBJS): Add spellcheck.o.
* spellcheck.c: New file.
* spellcheck.h: New file.
diff --git a/gcc/Makefile.in b/gcc/Makefile.in
index f17234d..21796f2 100644
--- a/gcc/Makefile.in
+++ b/gcc/Makefile.in
@@ -1158,7 +1158,7 @@ CXX_TARGET_OBJS=@cxx_target_objs@
FORTRAN_TARGET_OBJS=@fortran_target_objs@
# Object files for gcc many-languages driver.
-GCC_OBJS = gcc.o gcc-main.o ggc-none.o
+GCC_OBJS = gcc.o gcc-main.o ggc-none.o spellcheck.o
c-family-warn = $(STRICT_WARN)
@@ -1404,6 +1404,7 @@ OBJS = \
simplify-rtx.o \
sparseset.o \
spellcheck.o \
+ spellcheck-tree.o \
sreal.o \
stack-ptr-mod.o \
statistics.o \
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
diff --git a/gcc/spellcheck-tree.c b/gcc/spellcheck-tree.c
new file mode 100644
index 0000000..d203776
--- /dev/null
+++ b/gcc/spellcheck-tree.c
@@ -0,0 +1,39 @@
+/* Find near-matches for identifiers.
+ Copyright (C) 2015 Free Software Foundation, Inc.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 3, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3. If not see
+<http://www.gnu.org/licenses/>. */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
+#include "tree.h"
+#include "spellcheck.h"
+
+/* Calculate Levenshtein distance between two identifiers. */
+
+edit_distance_t
+levenshtein_distance (tree ident_s, tree ident_t)
+{
+ gcc_assert (TREE_CODE (ident_s) == IDENTIFIER_NODE);
+ gcc_assert (TREE_CODE (ident_t) == IDENTIFIER_NODE);
+
+ return levenshtein_distance (IDENTIFIER_POINTER (ident_s),
+ IDENTIFIER_LENGTH (ident_s),
+ IDENTIFIER_POINTER (ident_t),
+ IDENTIFIER_LENGTH (ident_t));
+}
diff --git a/gcc/spellcheck.c b/gcc/spellcheck.c
index 31ce322..32854cf 100644
--- a/gcc/spellcheck.c
+++ b/gcc/spellcheck.c
@@ -1,4 +1,4 @@
-/* Find near-matches for strings and identifiers.
+/* Find near-matches for strings.
Copyright (C) 2015 Free Software Foundation, Inc.
This file is part of GCC.
@@ -30,7 +30,7 @@ along with GCC; see the file COPYING3. If not see
This implementation uses the Wagner-Fischer algorithm. */
-static edit_distance_t
+edit_distance_t
levenshtein_distance (const char *s, int len_s,
const char *t, int len_t)
{
@@ -112,25 +112,10 @@ levenshtein_distance (const char *s, int len_s,
return result;
}
-/* Calculate Levenshtein distance between two nil-terminated strings.
- This exists purely for the unit tests. */
+/* Calculate Levenshtein distance between two nil-terminated strings. */
edit_distance_t
levenshtein_distance (const char *s, const char *t)
{
return levenshtein_distance (s, strlen (s), t, strlen (t));
}
-
-/* Calculate Levenshtein distance between two identifiers. */
-
-edit_distance_t
-levenshtein_distance (tree ident_s, tree ident_t)
-{
- gcc_assert (TREE_CODE (ident_s) == IDENTIFIER_NODE);
- gcc_assert (TREE_CODE (ident_t) == IDENTIFIER_NODE);
-
- return levenshtein_distance (IDENTIFIER_POINTER (ident_s),
- IDENTIFIER_LENGTH (ident_s),
- IDENTIFIER_POINTER (ident_t),
- IDENTIFIER_LENGTH (ident_t));
-}
diff --git a/gcc/spellcheck.h b/gcc/spellcheck.h
index 58355d6..673a756 100644
--- a/gcc/spellcheck.h
+++ b/gcc/spellcheck.h
@@ -24,6 +24,10 @@ typedef unsigned int edit_distance_t;
const edit_distance_t MAX_EDIT_DISTANCE = UINT_MAX;
extern edit_distance_t
+levenshtein_distance (const char *s, int len_s,
+ const char *t, int len_t);
+
+extern edit_distance_t
levenshtein_distance (const char *s, const char *t);
extern edit_distance_t
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 67299e0..409020a 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,5 +1,11 @@
2015-11-13 David Malcolm <dmalcolm@redhat.com>
+ PR driver/67613
+ * gcc/testsuite/gcc.dg/spellcheck-options-1.c: New file.
+ * gcc/testsuite/gcc.dg/spellcheck-options-2.c: New file.
+
+2015-11-13 David Malcolm <dmalcolm@redhat.com>
+
* gcc.dg/plugin/levenshtein-test-1.c: New file.
* gcc.dg/plugin/levenshtein_plugin.c: New file.
* gcc.dg/plugin/plugin.exp (plugin_test_list): Add
diff --git a/gcc/testsuite/gcc.dg/spellcheck-options-1.c b/gcc/testsuite/gcc.dg/spellcheck-options-1.c
new file mode 100644
index 0000000..cd5fdca
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/spellcheck-options-1.c
@@ -0,0 +1,4 @@
+/* { dg-do compile } */
+/* { dg-options "-Wcoercion" } */
+/* { dg-error "unrecognized command line option '-Wcoercion'; did you mean '-Wconversion'?" "" { target *-*-* } 0 } */
+
diff --git a/gcc/testsuite/gcc.dg/spellcheck-options-2.c b/gcc/testsuite/gcc.dg/spellcheck-options-2.c
new file mode 100644
index 0000000..786266d
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/spellcheck-options-2.c
@@ -0,0 +1,5 @@
+/* { dg-do compile } */
+/* { dg-options "-Wthis-should-not-get-a-hint" } */
+/* { dg-bogus "did you mean" "" { target *-*-* } 0 } */
+/* { dg-error "unrecognized command line option '-Wthis-should-not-get-a-hint'" "" { target *-*-* } 0 } */
+