Merge branch 'nd/diff-parseopt'

The diff machinery, one of the oldest parts of the system, which
long predates the parse-options API, uses fairly long and complex
handcrafted option parser.  This is being rewritten to use the
parse-options API.

* nd/diff-parseopt:
  diff.c: convert --raw
  diff.c: convert -W|--[no-]function-context
  diff.c: convert -U|--unified
  diff.c: convert -u|-p|--patch
  diff.c: prepare to use parse_options() for parsing
  diff.h: avoid bit fields in struct diff_flags
  diff.h: keep forward struct declarations sorted
  parse-options: allow ll_callback with OPTION_CALLBACK
  parse-options: avoid magic return codes
  parse-options: stop abusing 'callback' for lowlevel callbacks
  parse-options: add OPT_BITOP()
  parse-options: disable option abbreviation with PARSE_OPT_KEEP_UNKNOWN
  parse-options: add one-shot mode
  parse-options.h: remove extern on function prototypes
This commit is contained in:
Junio C Hamano
2019-03-07 09:59:52 +09:00
10 changed files with 319 additions and 159 deletions

71
diff.c
View File

@ -23,6 +23,7 @@
#include "argv-array.h"
#include "graph.h"
#include "packfile.h"
#include "parse-options.h"
#include "help.h"
#ifdef NO_FAST_WORKING_DIRECTORY
@ -4491,6 +4492,8 @@ static void run_checkdiff(struct diff_filepair *p, struct diff_options *o)
builtin_checkdiff(name, other, attr_path, p->one, p->two, o);
}
static void prep_parse_options(struct diff_options *options);
void repo_diff_setup(struct repository *r, struct diff_options *options)
{
memcpy(options, &default_diff_options, sizeof(*options));
@ -4532,6 +4535,8 @@ void repo_diff_setup(struct repository *r, struct diff_options *options)
options->color_moved = diff_color_moved_default;
options->color_moved_ws_handling = diff_color_moved_ws_default;
prep_parse_options(options);
}
void diff_setup_done(struct diff_options *options)
@ -4635,6 +4640,8 @@ void diff_setup_done(struct diff_options *options)
if (!options->use_color || external_diff())
options->color_moved = 0;
FREE_AND_NULL(options->parseopts);
}
static int opt_arg(const char *arg, int arg_short, const char *arg_long, int *val)
@ -4926,6 +4933,47 @@ static int parse_objfind_opt(struct diff_options *opt, const char *arg)
return 1;
}
static int diff_opt_unified(const struct option *opt,
const char *arg, int unset)
{
struct diff_options *options = opt->value;
char *s;
BUG_ON_OPT_NEG(unset);
options->context = strtol(arg, &s, 10);
if (*s)
return error(_("%s expects a numerical value"), "--unified");
enable_patch_output(&options->output_format);
return 0;
}
static void prep_parse_options(struct diff_options *options)
{
struct option parseopts[] = {
OPT_GROUP(N_("Diff output format options")),
OPT_BITOP('p', "patch", &options->output_format,
N_("generate patch"),
DIFF_FORMAT_PATCH, DIFF_FORMAT_NO_OUTPUT),
OPT_BITOP('u', NULL, &options->output_format,
N_("generate patch"),
DIFF_FORMAT_PATCH, DIFF_FORMAT_NO_OUTPUT),
OPT_CALLBACK_F('U', "unified", options, N_("<n>"),
N_("generate diffs with <n> lines context"),
PARSE_OPT_NONEG, diff_opt_unified),
OPT_BOOL('W', "function-context", &options->flags.funccontext,
N_("generate diffs with <n> lines context")),
OPT_BIT_F(0, "raw", &options->output_format,
N_("generate the diff in raw format"),
DIFF_FORMAT_RAW, PARSE_OPT_NONEG),
OPT_END()
};
ALLOC_ARRAY(options->parseopts, ARRAY_SIZE(parseopts));
memcpy(options->parseopts, parseopts, sizeof(parseopts));
}
int diff_opt_parse(struct diff_options *options,
const char **av, int ac, const char *prefix)
{
@ -4936,13 +4984,18 @@ int diff_opt_parse(struct diff_options *options,
if (!prefix)
prefix = "";
ac = parse_options(ac, av, prefix, options->parseopts, NULL,
PARSE_OPT_KEEP_DASHDASH |
PARSE_OPT_KEEP_UNKNOWN |
PARSE_OPT_NO_INTERNAL_HELP |
PARSE_OPT_ONE_SHOT |
PARSE_OPT_STOP_AT_NON_OPTION);
if (ac)
return ac;
/* Output format options */
if (!strcmp(arg, "-p") || !strcmp(arg, "-u") || !strcmp(arg, "--patch")
|| opt_arg(arg, 'U', "unified", &options->context))
enable_patch_output(&options->output_format);
else if (!strcmp(arg, "--raw"))
options->output_format |= DIFF_FORMAT_RAW;
else if (!strcmp(arg, "--patch-with-raw")) {
if (!strcmp(arg, "--patch-with-raw")) {
enable_patch_output(&options->output_format);
options->output_format |= DIFF_FORMAT_RAW;
} else if (!strcmp(arg, "--numstat"))
@ -5230,12 +5283,6 @@ int diff_opt_parse(struct diff_options *options,
else if (opt_arg(arg, '\0', "inter-hunk-context",
&options->interhunkcontext))
;
else if (!strcmp(arg, "-W"))
options->flags.funccontext = 1;
else if (!strcmp(arg, "--function-context"))
options->flags.funccontext = 1;
else if (!strcmp(arg, "--no-function-context"))
options->flags.funccontext = 0;
else if ((argcount = parse_long_opt("output", av, &optarg))) {
char *path = prefix_filename(prefix, optarg);
options->file = xfopen(path, "w");