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
This commit is contained in:
parent
277fe61691
commit
93ebf1fdbe
|
@ -1,3 +1,20 @@
|
|||
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.
|
||||
|
|
|
@ -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 \
|
||||
|
|
51
gcc/gcc.c
51
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
|
||||
|
|
|
@ -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));
|
||||
}
|
|
@ -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));
|
||||
}
|
||||
|
|
|
@ -23,6 +23,10 @@ along with GCC; see the file COPYING3. If not see
|
|||
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);
|
||||
|
||||
|
|
|
@ -1,3 +1,9 @@
|
|||
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.
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
/* { dg-do compile } */
|
||||
/* { dg-options "-Wcoercion" } */
|
||||
/* { dg-error "unrecognized command line option '-Wcoercion'; did you mean '-Wconversion'?" "" { target *-*-* } 0 } */
|
||||
|
|
@ -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 } */
|
||||
|
Loading…
Reference in New Issue