[m-rev.] for review: "Did you mean ..." mesages for long options
Zoltan Somogyi
zoltan.somogyi at runbox.com
Sat Apr 20 01:08:50 AEST 2024
On 2024-04-06 01:41 +11:00 AEST, "Julien Fischer" <jfischer at opturion.com> wrote:
> "Did you mean ..." messages for long options.
I intended to review this when you originally posted this, but forgot about it.
Sorry about that.
> Generate "Did you mean ..." messages for unrecognized long options.
> For example:
>
> unrecognized option `--no-half-at-wrn'.
> (Did you mean `--no-halt-at-warn'?)
>
> compiler/mercury_compile_main.m:
> If we have an unrecognized long option or negated long option,
> then attempt to generate a "Did you mean ..." message for it.
>
> compiler/error_spec.m:
> Add a version of maybe_construct_did_you_mean_pieces that lets
> you add prefix to the strings before including them in the pieces.
add A prefix
> maybe_construct_did_you_mean_pieces(BaseName, CandidateNames,
> DidYouMeanPieces) :-
> + do_maybe_construct_did_you_mean_pieces(BaseName, CandidateNames,
> + std_util.id, DidYouMeanPieces).
> +
> +maybe_construct_prefixed_did_you_mean_pieces(Prefix, BaseName, CandidateNames,
> + DidYouMeanPieces) :-
> + do_maybe_construct_did_you_mean_pieces(BaseName, CandidateNames,
> + add_prefix(Prefix), DidYouMeanPieces).
> +
> +:- pred do_maybe_construct_did_you_mean_pieces(string::in, list(string)::in,
> + (func(string) = string)::in, list(format_piece)::out) is det.
> +
> +do_maybe_construct_did_you_mean_pieces(BaseName, CandidateNames,
> + TransformFunc, DidYouMeanPieces) :-
You may need a space before the :-.
> + % Add to stdlib? string.append has wrong mode for list map.
> + %
> +:- func add_prefix(string, string) = string.
> +
> +add_prefix(Prefix, String) = Prefix ++ String.
I would say yes, add add_prefix to string.m, together with add_suffix (which would take
the suffix arg as its first arg).
> diff --git a/compiler/mercury_compile_main.m b/compiler/mercury_compile_main.m
> index 08325be..a58eaf2 100644
> --- a/compiler/mercury_compile_main.m
> +++ b/compiler/mercury_compile_main.m
> @@ -392,10 +392,8 @@ process_options_std(ProgressStream, ErrorStream, DefaultOptionTable,
> DefaultOptionTable, ArgsOptionTable, cord.init, _UserData, !IO),
> (
> MaybeError = yes(OptionError),
> - OptionErrorStr = option_error_to_string(OptionError),
> - Spec = simplest_no_context_spec($pred, severity_error,
> - phase_options, [words(OptionErrorStr), suffix("."), nl]),
> - Result = opr_failure([Spec])
> + Specs = make_option_error(OptionError),
> + Result = opr_failure(Specs)
make_option_error seems a strange name for this function;
I would use something like report_bad_option.
> +:- func make_option_error(option_error(option)) = list(error_spec).
> +
> +make_option_error(OptionError) = Specs :-
> + OptionErrorStr = option_error_to_string(OptionError),
> + ( if
> + OptionError = unrecognized_option(OptionStr),
> + ( if string.remove_prefix("--no-", OptionStr, BaseOptionStr0) then
> + IsNegatedOption = yes,
> + BaseOptionStr = BaseOptionStr0
> + else if string.remove_prefix("--", OptionStr, BaseOptionStr0) then
> + IsNegatedOption = no,
> + BaseOptionStr = BaseOptionStr0
> + else
> + false
> + ),
> + not is_empty(BaseOptionStr)
Why not is_empty(BaseOptionStr) instead of BaseOptionStr \= ""?
And this code checks only for long options. On lines 1123 and 1369 of getopt.m,
we can construct unrecognized_option errors for short options as well.
The techniques you use on long options in options.m would work for
short options as well. I presume you rejected that because for short options,
there are no good dym suggestions, so I would add a comment to that effect
just above the "fail" (we usually use that, not "false").
> +:- pred long_option_table(string, option).
> +:- mode long_option_table(in, out) is semidet.
> +:- mode long_option_table(out, out) is multi.
We already have trouble with long option names causing too-long lines.
If we need to switch to a name different than long_table, I would pick
a *shorter* name. I would even be fine with "lo" as the name, with a comment
explaining the line length issue and the fact that it stands for "long option".
The diff is otherwise fine.
Zoltan.
More information about the reviews
mailing list