diff-parseopt: convert --output-*

This also validates that the user specifies a single character in --output-indicator-*, not a string. Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Nguyễn Thái Ngọc Duy committed Feb 21, 2019 at 18:16 UTC af2f36809182c24ee92d3b13ed3cc5a1fb6e10df
2 files changed +63 -18
Documentation/diff-options.txt
+10
@@ -41,6 +41,16 @@ ifndef::git-format-patch[]
41 Implies `-p`.
42 endif::git-format-patch[]
43
44 +--output=<file>::
45 + Output to a specific file instead of stdout.
46 +
47 +--output-indicator-new=<char>::
48 +--output-indicator-old=<char>::
49 +--output-indicator-context=<char>::
50 + Specify the character used to indicate new, old or context
51 + lines in the generated patch. Normally they are '+', '-' and
52 + ' ' respectively.
53 +
54 ifndef::git-format-patch[]
55 --raw::
56 ifndef::git-log[]
diff.c
+53 -18
@@ -4841,6 +4841,19 @@ static int parse_objfind_opt(struct diff_options *opt, const char *arg)
4841 return 1;
4842 }
4843
4844 +static int diff_opt_char(const struct option *opt,
4845 + const char *arg, int unset)
4846 +{
4847 + char *value = opt->value;
4848 +
4849 + BUG_ON_OPT_NEG(unset);
4850 + if (arg[1])
4851 + return error(_("%s expects a character, got '%s'"),
4852 + opt->long_name, arg);
4853 + *value = arg[0];
4854 + return 0;
4855 +}
4856 +
4857 static int diff_opt_compact_summary(const struct option *opt,
4858 const char *arg, int unset)
4859 {
@@ -4872,6 +4885,23 @@ static int diff_opt_dirstat(const struct option *opt,
4885 return 0;
4886 }
4887
4888 +static enum parse_opt_result diff_opt_output(struct parse_opt_ctx_t *ctx,
4889 + const struct option *opt,
4890 + const char *arg, int unset)
4891 +{
4892 + struct diff_options *options = opt->value;
4893 + char *path;
4894 +
4895 + BUG_ON_OPT_NEG(unset);
4896 + path = prefix_filename(ctx->prefix, arg);
4897 + options->file = xfopen(path, "w");
4898 + options->close_file = 1;
4899 + if (options->use_color != GIT_COLOR_ALWAYS)
4900 + options->use_color = GIT_COLOR_NEVER;
4901 + free(path);
4902 + return 0;
4903 +}
4904 +
4905 static int diff_opt_unified(const struct option *opt,
4906 const char *arg, int unset)
4907 {
@@ -4965,6 +4995,27 @@ static void prep_parse_options(struct diff_options *options)
4995 OPT_CALLBACK_F(0, "compact-summary", options, NULL,
4996 N_("generate compact summary in diffstat"),
4997 PARSE_OPT_NOARG, diff_opt_compact_summary),
4998 + OPT_CALLBACK_F(0, "output-indicator-new",
4999 + &options->output_indicators[OUTPUT_INDICATOR_NEW],
5000 + N_("<char>"),
5001 + N_("specify the character to indicate a new line instead of '+'"),
5002 + PARSE_OPT_NONEG, diff_opt_char),
5003 + OPT_CALLBACK_F(0, "output-indicator-old",
5004 + &options->output_indicators[OUTPUT_INDICATOR_OLD],
5005 + N_("<char>"),
5006 + N_("specify the character to indicate an old line instead of '-'"),
5007 + PARSE_OPT_NONEG, diff_opt_char),
5008 + OPT_CALLBACK_F(0, "output-indicator-context",
5009 + &options->output_indicators[OUTPUT_INDICATOR_CONTEXT],
5010 + N_("<char>"),
5011 + N_("specify the character to indicate a context instead of ' '"),
5012 + PARSE_OPT_NONEG, diff_opt_char),
5013 +
5014 + OPT_GROUP(N_("Diff other options")),
5015 + { OPTION_CALLBACK, 0, "output", options, N_("<file>"),
5016 + N_("Output to a specific file"),
5017 + PARSE_OPT_NONEG, NULL, 0, diff_opt_output },
5018 +
5019 OPT_END()
5020 };
5021
@@ -4992,16 +5043,8 @@ int diff_opt_parse(struct diff_options *options,
5043 if (ac)
5044 return ac;
5045
4995 - /* Output format options */
4996 - if (skip_prefix(arg, "--output-indicator-new=", &arg))
4997 - options->output_indicators[OUTPUT_INDICATOR_NEW] = arg[0];
4998 - else if (skip_prefix(arg, "--output-indicator-old=", &arg))
4999 - options->output_indicators[OUTPUT_INDICATOR_OLD] = arg[0];
5000 - else if (skip_prefix(arg, "--output-indicator-context=", &arg))
5001 - options->output_indicators[OUTPUT_INDICATOR_CONTEXT] = arg[0];
5002 -
5046 /* renames options */
5004 - else if (starts_with(arg, "-B") ||
5047 + if (starts_with(arg, "-B") ||
5048 skip_to_optional_arg(arg, "--break-rewrites", NULL)) {
5049 if ((options->break_opt = diff_scoreopt_parse(arg)) == -1)
5050 return error("invalid argument to -B: %s", arg+2);
@@ -5242,15 +5285,7 @@ int diff_opt_parse(struct diff_options *options,
5285 else if (opt_arg(arg, '\0', "inter-hunk-context",
5286 &options->interhunkcontext))
5287 ;
5245 - else if ((argcount = parse_long_opt("output", av, &optarg))) {
5246 - char *path = prefix_filename(prefix, optarg);
5247 - options->file = xfopen(path, "w");
5248 - options->close_file = 1;
5249 - if (options->use_color != GIT_COLOR_ALWAYS)
5250 - options->use_color = GIT_COLOR_NEVER;
5251 - free(path);
5252 - return argcount;
5253 - } else
5288 + else
5289 return 0;
5290 return 1;
5291 }