re PR middle-end/77475 (unnecessary or misleading context in reporting command line...
authorJakub Jelinek <jakub@redhat.com>
Tue, 13 Sep 2016 08:45:36 +0000 (10:45 +0200)
committerJakub Jelinek <jakub@gcc.gnu.org>
Tue, 13 Sep 2016 08:45:36 +0000 (10:45 +0200)
PR middle-end/77475
* opts.h (candidates_list_and_hint): Declare.
* opts-common.c (candidates_list_and_hint): New function.
(cmdline_handle_error): Use it.

Co-Authored-By: Manuel López-Ibáñez <manu@gcc.gnu.org>
From-SVN: r240107

gcc/ChangeLog
gcc/opts-common.c
gcc/opts.h

index c0d8efa..ad74cc1 100644 (file)
@@ -1,3 +1,11 @@
+2016-09-13  Jakub Jelinek  <jakub@redhat.com>
+           Manuel Lopez-Ibanez  <manu@gcc.gnu.org>
+
+       PR middle-end/77475
+       * opts.h (candidates_list_and_hint): Declare.
+       * opts-common.c (candidates_list_and_hint): New function.
+       (cmdline_handle_error): Use it.
+
 2016-09-12  David Malcolm  <dmalcolm@redhat.com>
 
        * edit-context.c (edited_line::get_len): New accessor.
index 8634b52..e9d1c20 100644 (file)
@@ -1069,6 +1069,38 @@ generate_option_input_file (const char *file,
   decoded->errors = 0;
 }
 
+/* Helper function for listing valid choices and hint for misspelled
+   value.  CANDIDATES is a vector containing all valid strings,
+   STR is set to a heap allocated string that contains all those
+   strings concatenated, separated by spaces, and the return value
+   is the closest string from those to ARG, or NULL if nothing is
+   close enough.  Callers should XDELETEVEC (STR) after using it
+   to avoid memory leaks.  */
+
+const char *
+candidates_list_and_hint (const char *arg, char *&str,
+                         const auto_vec <const char *> &candidates)
+{
+  size_t len = 0;
+  int i;
+  const char *candidate;
+  char *p;
+
+  FOR_EACH_VEC_ELT (candidates, i, candidate)
+    len += strlen (candidate) + 1;
+
+  str = p = XNEWVEC (char, len);
+  FOR_EACH_VEC_ELT (candidates, i, candidate)
+    {
+      len = strlen (candidate);
+      memcpy (p, candidate, len);
+      p[len] = ' ';
+      p += len + 1;
+    }
+  p[-1] = '\0';
+  return find_closest_string (arg, &candidates);
+}
+
 /* Perform diagnostics for read_cmdline_option and control_warning_option
    functions.  Returns true if an error has been diagnosed.
    LOC and LANG_MASK arguments like in read_cmdline_option.
@@ -1108,38 +1140,27 @@ cmdline_handle_error (location_t loc, const struct cl_option *option,
     {
       const struct cl_enum *e = &cl_enums[option->var_enum];
       unsigned int i;
-      size_t len;
-      char *s, *p;
+      char *s;
 
       if (e->unknown_error)
        error_at (loc, e->unknown_error, arg);
       else
        error_at (loc, "unrecognized argument in option %qs", opt);
 
-      len = 0;
-      for (i = 0; e->values[i].arg != NULL; i++)
-       len += strlen (e->values[i].arg) + 1;
-
       auto_vec <const char *> candidates;
-      s = XALLOCAVEC (char, len);
-      p = s;
       for (i = 0; e->values[i].arg != NULL; i++)
        {
          if (!enum_arg_ok_for_language (&e->values[i], lang_mask))
            continue;
-         size_t arglen = strlen (e->values[i].arg);
-         memcpy (p, e->values[i].arg, arglen);
-         p[arglen] = ' ';
-         p += arglen + 1;
          candidates.safe_push (e->values[i].arg);
        }
-      p[-1] = 0;
-      const char *hint = find_closest_string (arg, &candidates);
+      const char *hint = candidates_list_and_hint (arg, s, candidates);
       if (hint)
        inform (loc, "valid arguments to %qs are: %s; did you mean %qs?",
                option->opt_text, s, hint);
       else
        inform (loc, "valid arguments to %qs are: %s", option->opt_text, s);
+      XDELETEVEC (s);
 
       return true;
     }
index 25d32c1..4132432 100644 (file)
@@ -419,5 +419,8 @@ extern const struct sanitizer_opts_s
 extern void add_misspelling_candidates (auto_vec<char *> *candidates,
                                        const struct cl_option *option,
                                        const char *base_option);
+extern const char *candidates_list_and_hint (const char *arg, char *&str,
+                                            const auto_vec <const char *> &
+                                            candidates);
 
 #endif