Hi! On Mon, Sep 05, 2016 at 09:59:03PM +0200, Jakub Jelinek wrote: > Plus obviously the unrecognized_argument_error needs to be declared in some > header file. > > That said, for x86 -march/-mtune uses this is problematic, as it uses either > %<-march=%> argument or target("march=") attribute wording there depending > on whether it is a command line option or target attribute. Though, it is > not good this way for translation anyway. Perhaps use XNEWVEC instead of > XALLOCAVEC for the all options string, and have the helper function just > return that + hint, inform by itself and then free the string?
Here is the generic part that does this (and it indeed simplifies quite a lot the i386.c patch, while keeping the diagnostics in its hands for exact wording etc.). Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk? 2016-09-06 Jakub Jelinek <ja...@redhat.com> Manuel Lopez-Ibanez <m...@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. --- gcc/opts.h.jj 2016-06-30 19:38:45.000000000 +0200 +++ gcc/opts.h 2016-09-06 18:05:50.836734668 +0200 @@ -419,5 +420,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 --- gcc/opts-common.c.jj 2016-06-30 19:38:45.000000000 +0200 +++ gcc/opts-common.c 2016-09-06 19:36:22.339827679 +0200 @@ -1069,6 +1069,37 @@ generate_option_input_file (const char * 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. */ + +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 +1139,27 @@ cmdline_handle_error (location_t loc, co { 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; } Jakub