Merge branch 'nd/diff-parseopt-4'

Fourth batch to teach the diff machinery to use the parse-options
API.

* nd/diff-parseopt-4:
  am: avoid diff_opt_parse()
  diff --no-index: use parse_options() instead of diff_opt_parse()
  range-diff: use parse_options() instead of diff_opt_parse()
  diff.c: allow --no-color-moved-ws
  diff-parseopt: convert --color-moved-ws
  diff-parseopt: convert --[no-]color-moved
  diff-parseopt: convert --inter-hunk-context
  diff-parseopt: convert --no-prefix
  diff-parseopt: convert --line-prefix
  diff-parseopt: convert --[src|dst]-prefix
  diff-parseopt: convert --[no-]abbrev
  diff-parseopt: convert --diff-filter
  diff-parseopt: convert --find-object
  diff-parseopt: convert -O
  diff-parseopt: convert --pickaxe-all|--pickaxe-regex
  diff-parseopt: convert -S|-G
  diff-parseopt: convert -l
  diff-parseopt: convert -z
  diff-parseopt: convert --ita-[in]visible-in-index
  diff-parseopt: convert --ws-error-highlight
This commit is contained in:
Junio C Hamano
2019-04-25 16:41:12 +09:00
9 changed files with 219 additions and 239 deletions

339
diff.c
View File

@ -4640,66 +4640,6 @@ void diff_setup_done(struct diff_options *options)
FREE_AND_NULL(options->parseopts);
}
static int opt_arg(const char *arg, int arg_short, const char *arg_long, int *val)
{
char c, *eq;
int len;
if (*arg != '-')
return 0;
c = *++arg;
if (!c)
return 0;
if (c == arg_short) {
c = *++arg;
if (!c)
return 1;
if (val && isdigit(c)) {
char *end;
int n = strtoul(arg, &end, 10);
if (*end)
return 0;
*val = n;
return 1;
}
return 0;
}
if (c != '-')
return 0;
arg++;
eq = strchrnul(arg, '=');
len = eq - arg;
if (!len || strncmp(arg, arg_long, len))
return 0;
if (*eq) {
int n;
char *end;
if (!isdigit(*++eq))
return 0;
n = strtoul(eq, &end, 10);
if (*end)
return 0;
*val = n;
}
return 1;
}
static inline int short_opt(char opt, const char **argv,
const char **optarg)
{
const char *arg = argv[0];
if (arg[0] != '-' || arg[1] != opt)
return 0;
if (arg[2] != '\0') {
*optarg = arg + 2;
return 1;
}
if (!argv[1])
die("Option '%c' requires a value", opt);
*optarg = argv[1];
return 2;
}
int parse_long_opt(const char *opt, const char **argv,
const char **optarg)
{
@ -4819,10 +4759,19 @@ static unsigned filter_bit_tst(char status, const struct diff_options *opt)
return opt->filter & filter_bit[(int) status];
}
static int parse_diff_filter_opt(const char *optarg, struct diff_options *opt)
unsigned diff_filter_bit(char status)
{
prepare_filter_bits();
return filter_bit[(int) status];
}
static int diff_opt_diff_filter(const struct option *option,
const char *optarg, int unset)
{
struct diff_options *opt = option->value;
int i, optch;
BUG_ON_OPT_NEG(unset);
prepare_filter_bits();
/*
@ -4853,7 +4802,8 @@ static int parse_diff_filter_opt(const char *optarg, struct diff_options *opt)
bit = (0 <= optch && optch <= 'Z') ? filter_bit[optch] : 0;
if (!bit)
return optarg[i];
return error(_("unknown change class '%c' in --diff-filter=%s"),
optarg[i], optarg);
if (negate)
opt->filter &= ~bit;
else
@ -4868,25 +4818,29 @@ static void enable_patch_output(int *fmt)
*fmt |= DIFF_FORMAT_PATCH;
}
static int parse_ws_error_highlight_opt(struct diff_options *opt, const char *arg)
static int diff_opt_ws_error_highlight(const struct option *option,
const char *arg, int unset)
{
struct diff_options *opt = option->value;
int val = parse_ws_error_highlight(arg);
if (val < 0) {
error("unknown value after ws-error-highlight=%.*s",
-1 - val, arg);
return 0;
}
BUG_ON_OPT_NEG(unset);
if (val < 0)
return error(_("unknown value after ws-error-highlight=%.*s"),
-1 - val, arg);
opt->ws_error_highlight = val;
return 1;
return 0;
}
static int parse_objfind_opt(struct diff_options *opt, const char *arg)
static int diff_opt_find_object(const struct option *option,
const char *arg, int unset)
{
struct diff_options *opt = option->value;
struct object_id oid;
BUG_ON_OPT_NEG(unset);
if (get_oid(arg, &oid))
return error("unable to resolve '%s'", arg);
return error(_("unable to resolve '%s'"), arg);
if (!opt->objfind)
opt->objfind = xcalloc(1, sizeof(*opt->objfind));
@ -4895,7 +4849,7 @@ static int parse_objfind_opt(struct diff_options *opt, const char *arg)
opt->flags.recursive = 1;
opt->flags.tree_in_recursive = 1;
oidset_insert(opt->objfind, &oid);
return 1;
return 0;
}
static int diff_opt_anchored(const struct option *opt,
@ -4960,6 +4914,45 @@ static int diff_opt_char(const struct option *opt,
return 0;
}
static int diff_opt_color_moved(const struct option *opt,
const char *arg, int unset)
{
struct diff_options *options = opt->value;
if (unset) {
options->color_moved = COLOR_MOVED_NO;
} else if (!arg) {
if (diff_color_moved_default)
options->color_moved = diff_color_moved_default;
if (options->color_moved == COLOR_MOVED_NO)
options->color_moved = COLOR_MOVED_DEFAULT;
} else {
int cm = parse_color_moved(arg);
if (cm < 0)
return error(_("bad --color-moved argument: %s"), arg);
options->color_moved = cm;
}
return 0;
}
static int diff_opt_color_moved_ws(const struct option *opt,
const char *arg, int unset)
{
struct diff_options *options = opt->value;
unsigned cm;
if (unset) {
options->color_moved_ws_handling = 0;
return 0;
}
cm = parse_color_moved_ws(arg);
if (cm & COLOR_MOVED_WS_ERROR)
return error(_("invalid mode '%s' in --color-moved-ws"), arg);
options->color_moved_ws_handling = cm;
return 0;
}
static int diff_opt_color_words(const struct option *opt,
const char *arg, int unset)
{
@ -5085,6 +5078,30 @@ static int diff_opt_ignore_submodules(const struct option *opt,
return 0;
}
static int diff_opt_line_prefix(const struct option *opt,
const char *optarg, int unset)
{
struct diff_options *options = opt->value;
BUG_ON_OPT_NEG(unset);
options->line_prefix = optarg;
options->line_prefix_length = strlen(options->line_prefix);
graph_setup_line_prefix(options);
return 0;
}
static int diff_opt_no_prefix(const struct option *opt,
const char *optarg, int unset)
{
struct diff_options *options = opt->value;
BUG_ON_OPT_NEG(unset);
BUG_ON_OPT_ARG(optarg);
options->a_prefix = "";
options->b_prefix = "";
return 0;
}
static enum parse_opt_result diff_opt_output(struct parse_opt_ctx_t *ctx,
const struct option *opt,
const char *arg, int unset)
@ -5122,6 +5139,28 @@ static int diff_opt_patience(const struct option *opt,
return 0;
}
static int diff_opt_pickaxe_regex(const struct option *opt,
const char *arg, int unset)
{
struct diff_options *options = opt->value;
BUG_ON_OPT_NEG(unset);
options->pickaxe = arg;
options->pickaxe_opts |= DIFF_PICKAXE_KIND_G;
return 0;
}
static int diff_opt_pickaxe_string(const struct option *opt,
const char *arg, int unset)
{
struct diff_options *options = opt->value;
BUG_ON_OPT_NEG(unset);
options->pickaxe = arg;
options->pickaxe_opts |= DIFF_PICKAXE_KIND_S;
return 0;
}
static int diff_opt_relative(const struct option *opt,
const char *arg, int unset)
{
@ -5301,6 +5340,28 @@ static void prep_parse_options(struct diff_options *options)
N_("show full pre- and post-image object names on the \"index\" lines")),
OPT_COLOR_FLAG(0, "color", &options->use_color,
N_("show colored diff")),
OPT_CALLBACK_F(0, "ws-error-highlight", options, N_("<kind>"),
N_("highlight whitespace errors in the 'context', 'old' or 'new' lines in the diff"),
PARSE_OPT_NONEG, diff_opt_ws_error_highlight),
OPT_SET_INT('z', NULL, &options->line_termination,
N_("do not munge pathnames and use NULs as output field terminators in --raw or --numstat"),
0),
OPT__ABBREV(&options->abbrev),
OPT_STRING_F(0, "src-prefix", &options->a_prefix, N_("<prefix>"),
N_("show the given source prefix instead of \"a/\""),
PARSE_OPT_NONEG),
OPT_STRING_F(0, "dst-prefix", &options->b_prefix, N_("<prefix>"),
N_("show the given source prefix instead of \"b/\""),
PARSE_OPT_NONEG),
OPT_CALLBACK_F(0, "line-prefix", options, N_("<prefix>"),
N_("prepend an additional prefix to every line of output"),
PARSE_OPT_NONEG, diff_opt_line_prefix),
OPT_CALLBACK_F(0, "no-prefix", options, NULL,
N_("do not show any source or destination prefix"),
PARSE_OPT_NONEG | PARSE_OPT_NOARG, diff_opt_no_prefix),
OPT_INTEGER_F(0, "inter-hunk-context", &options->interhunkcontext,
N_("show context between diff hunks up to the specified number of lines"),
PARSE_OPT_NONEG),
OPT_CALLBACK_F(0, "output-indicator-new",
&options->output_indicators[OUTPUT_INDICATOR_NEW],
N_("<char>"),
@ -5343,6 +5404,8 @@ static void prep_parse_options(struct diff_options *options)
OPT_CALLBACK_F(0, "follow", options, NULL,
N_("continue listing the history of a file beyond renames"),
PARSE_OPT_NOARG, diff_opt_follow),
OPT_INTEGER('l', NULL, &options->rename_limit,
N_("prevent rename/copy detection if the number of rename/copy targets exceeds given limit")),
OPT_GROUP(N_("Diff algorithm options")),
OPT_BIT(0, "minimal", &options->xdl_opts,
@ -5388,6 +5451,12 @@ static void prep_parse_options(struct diff_options *options)
OPT_CALLBACK_F(0, "color-words", options, N_("<regex>"),
N_("equivalent to --word-diff=color --word-diff-regex=<regex>"),
PARSE_OPT_NONEG | PARSE_OPT_OPTARG, diff_opt_color_words),
OPT_CALLBACK_F(0, "color-moved", options, N_("<mode>"),
N_("move lines of code are colored differently"),
PARSE_OPT_OPTARG, diff_opt_color_moved),
OPT_CALLBACK_F(0, "color-moved-ws", options, N_("<mode>"),
N_("how white spaces are ignored in --color-moved"),
0, diff_opt_color_moved_ws),
OPT_GROUP(N_("Diff other options")),
OPT_CALLBACK_F(0, "relative", options, N_("<prefix>"),
@ -5415,6 +5484,32 @@ static void prep_parse_options(struct diff_options *options)
N_("specify how differences in submodules are shown"),
PARSE_OPT_NONEG | PARSE_OPT_OPTARG,
diff_opt_submodule),
OPT_SET_INT_F(0, "ita-invisible-in-index", &options->ita_invisible_in_index,
N_("hide 'git add -N' entries from the index"),
1, PARSE_OPT_NONEG),
OPT_SET_INT_F(0, "ita-visible-in-index", &options->ita_invisible_in_index,
N_("treat 'git add -N' entries as real in the index"),
0, PARSE_OPT_NONEG),
OPT_CALLBACK_F('S', NULL, options, N_("<string>"),
N_("look for differences that change the number of occurrences of the specified string"),
0, diff_opt_pickaxe_string),
OPT_CALLBACK_F('G', NULL, options, N_("<regex>"),
N_("look for differences that change the number of occurrences of the specified regex"),
0, diff_opt_pickaxe_regex),
OPT_BIT_F(0, "pickaxe-all", &options->pickaxe_opts,
N_("show all changes in the changeset with -S or -G"),
DIFF_PICKAXE_ALL, PARSE_OPT_NONEG),
OPT_BIT_F(0, "pickaxe-regex", &options->pickaxe_opts,
N_("treat <string> in -S as extended POSIX regular expression"),
DIFF_PICKAXE_REGEX, PARSE_OPT_NONEG),
OPT_FILENAME('O', NULL, &options->orderfile,
N_("control the order in which files appear in the output")),
OPT_CALLBACK_F(0, "find-object", options, N_("<object-id>"),
N_("look for differences that change the number of occurrences of the specified object"),
PARSE_OPT_NONEG, diff_opt_find_object),
OPT_CALLBACK_F(0, "diff-filter", options, N_("[(A|C|D|M|R|T|U|X|B)...[*]]"),
N_("select files by diff type"),
PARSE_OPT_NONEG, diff_opt_diff_filter),
{ OPTION_CALLBACK, 0, "output", options, N_("<file>"),
N_("Output to a specific file"),
PARSE_OPT_NONEG, NULL, 0, diff_opt_output },
@ -5429,10 +5524,6 @@ static void prep_parse_options(struct diff_options *options)
int diff_opt_parse(struct diff_options *options,
const char **av, int ac, const char *prefix)
{
const char *arg = av[0];
const char *optarg;
int argcount;
if (!prefix)
prefix = "";
@ -5443,101 +5534,7 @@ int diff_opt_parse(struct diff_options *options,
PARSE_OPT_ONE_SHOT |
PARSE_OPT_STOP_AT_NON_OPTION);
if (ac)
return ac;
/* flags options */
if (!strcmp(arg, "--color-moved")) {
if (diff_color_moved_default)
options->color_moved = diff_color_moved_default;
if (options->color_moved == COLOR_MOVED_NO)
options->color_moved = COLOR_MOVED_DEFAULT;
} else if (!strcmp(arg, "--no-color-moved"))
options->color_moved = COLOR_MOVED_NO;
else if (skip_prefix(arg, "--color-moved=", &arg)) {
int cm = parse_color_moved(arg);
if (cm < 0)
return error("bad --color-moved argument: %s", arg);
options->color_moved = cm;
} else if (!strcmp(arg, "--no-color-moved-ws")) {
options->color_moved_ws_handling = 0;
} else if (skip_prefix(arg, "--color-moved-ws=", &arg)) {
unsigned cm = parse_color_moved_ws(arg);
if (cm & COLOR_MOVED_WS_ERROR)
return -1;
options->color_moved_ws_handling = cm;
} else if (skip_prefix(arg, "--ws-error-highlight=", &arg))
return parse_ws_error_highlight_opt(options, arg);
else if (!strcmp(arg, "--ita-invisible-in-index"))
options->ita_invisible_in_index = 1;
else if (!strcmp(arg, "--ita-visible-in-index"))
options->ita_invisible_in_index = 0;
/* misc options */
else if (!strcmp(arg, "-z"))
options->line_termination = 0;
else if ((argcount = short_opt('l', av, &optarg))) {
options->rename_limit = strtoul(optarg, NULL, 10);
return argcount;
}
else if ((argcount = short_opt('S', av, &optarg))) {
options->pickaxe = optarg;
options->pickaxe_opts |= DIFF_PICKAXE_KIND_S;
return argcount;
} else if ((argcount = short_opt('G', av, &optarg))) {
options->pickaxe = optarg;
options->pickaxe_opts |= DIFF_PICKAXE_KIND_G;
return argcount;
}
else if (!strcmp(arg, "--pickaxe-all"))
options->pickaxe_opts |= DIFF_PICKAXE_ALL;
else if (!strcmp(arg, "--pickaxe-regex"))
options->pickaxe_opts |= DIFF_PICKAXE_REGEX;
else if ((argcount = short_opt('O', av, &optarg))) {
options->orderfile = prefix_filename(prefix, optarg);
return argcount;
} else if (skip_prefix(arg, "--find-object=", &arg))
return parse_objfind_opt(options, arg);
else if ((argcount = parse_long_opt("diff-filter", av, &optarg))) {
int offending = parse_diff_filter_opt(optarg, options);
if (offending)
die("unknown change class '%c' in --diff-filter=%s",
offending, optarg);
return argcount;
}
else if (!strcmp(arg, "--no-abbrev"))
options->abbrev = 0;
else if (!strcmp(arg, "--abbrev"))
options->abbrev = DEFAULT_ABBREV;
else if (skip_prefix(arg, "--abbrev=", &arg)) {
options->abbrev = strtoul(arg, NULL, 10);
if (options->abbrev < MINIMUM_ABBREV)
options->abbrev = MINIMUM_ABBREV;
else if (the_hash_algo->hexsz < options->abbrev)
options->abbrev = the_hash_algo->hexsz;
}
else if ((argcount = parse_long_opt("src-prefix", av, &optarg))) {
options->a_prefix = optarg;
return argcount;
}
else if ((argcount = parse_long_opt("line-prefix", av, &optarg))) {
options->line_prefix = optarg;
options->line_prefix_length = strlen(options->line_prefix);
graph_setup_line_prefix(options);
return argcount;
}
else if ((argcount = parse_long_opt("dst-prefix", av, &optarg))) {
options->b_prefix = optarg;
return argcount;
}
else if (!strcmp(arg, "--no-prefix"))
options->a_prefix = options->b_prefix = "";
else if (opt_arg(arg, '\0', "inter-hunk-context",
&options->interhunkcontext))
;
else
return 0;
return 1;
return ac;
}
int parse_rename_score(const char **cp_p)