apply: refactor `git apply` option parsing

Parsing `git apply` options can be useful to other commands that want to call the libified apply functionality, because this way they can easily pass some options from their own command line to the libified apply functionality. This will be used by `git am` in a following patch. To make this possible, let's refactor the `git apply` option parsing code into a new libified apply_parse_options() function. Doing that makes it possible to remove some functions definitions from "apply.h" and make them static in "apply.c". Helped-by: Ramsay Jones <ramsay@ramsayjones.plus.com> Signed-off-by: Christian Couder <chriscool@tuxfamily.org> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Christian Couder committed Sep 4, 2016 at 22:18 UTC 7e1bad24e3b7f220813d8a449f19652113edb923
3 files changed +97 -98
apply.c
+90 -13
@@ -4730,16 +4730,16 @@ end:
4730 return res;
4731 }
4732
4733 -int apply_option_parse_exclude(const struct option *opt,
4734 - const char *arg, int unset)
4733 +static int apply_option_parse_exclude(const struct option *opt,
4734 + const char *arg, int unset)
4735 {
4736 struct apply_state *state = opt->value;
4737 add_name_limit(state, arg, 1);
4738 return 0;
4739 }
4740
4741 -int apply_option_parse_include(const struct option *opt,
4742 - const char *arg, int unset)
4741 +static int apply_option_parse_include(const struct option *opt,
4742 + const char *arg, int unset)
4743 {
4744 struct apply_state *state = opt->value;
4745 add_name_limit(state, arg, 0);
@@ -4747,9 +4747,9 @@ int apply_option_parse_include(const struct option *opt,
4747 return 0;
4748 }
4749
4750 -int apply_option_parse_p(const struct option *opt,
4751 - const char *arg,
4752 - int unset)
4750 +static int apply_option_parse_p(const struct option *opt,
4751 + const char *arg,
4752 + int unset)
4753 {
4754 struct apply_state *state = opt->value;
4755 state->p_value = atoi(arg);
@@ -4757,8 +4757,8 @@ int apply_option_parse_p(const struct option *opt,
4757 return 0;
4758 }
4759
4760 -int apply_option_parse_space_change(const struct option *opt,
4761 - const char *arg, int unset)
4760 +static int apply_option_parse_space_change(const struct option *opt,
4761 + const char *arg, int unset)
4762 {
4763 struct apply_state *state = opt->value;
4764 if (unset)
@@ -4768,8 +4768,8 @@ int apply_option_parse_space_change(const struct option *opt,
4768 return 0;
4769 }
4770
4771 -int apply_option_parse_whitespace(const struct option *opt,
4772 - const char *arg, int unset)
4771 +static int apply_option_parse_whitespace(const struct option *opt,
4772 + const char *arg, int unset)
4773 {
4774 struct apply_state *state = opt->value;
4775 state->whitespace_option = arg;
@@ -4778,8 +4778,8 @@ int apply_option_parse_whitespace(const struct option *opt,
4778 return 0;
4779 }
4780
4781 -int apply_option_parse_directory(const struct option *opt,
4782 - const char *arg, int unset)
4781 +static int apply_option_parse_directory(const struct option *opt,
4782 + const char *arg, int unset)
4783 {
4784 struct apply_state *state = opt->value;
4785 strbuf_reset(&state->root);
@@ -4893,3 +4893,80 @@ end:
4893 return res;
4894 return (res == -1 ? 1 : 128);
4895 }
4896 +
4897 +int apply_parse_options(int argc, const char **argv,
4898 + struct apply_state *state,
4899 + int *force_apply, int *options,
4900 + const char * const *apply_usage)
4901 +{
4902 + struct option builtin_apply_options[] = {
4903 + { OPTION_CALLBACK, 0, "exclude", state, N_("path"),
4904 + N_("don't apply changes matching the given path"),
4905 + 0, apply_option_parse_exclude },
4906 + { OPTION_CALLBACK, 0, "include", state, N_("path"),
4907 + N_("apply changes matching the given path"),
4908 + 0, apply_option_parse_include },
4909 + { OPTION_CALLBACK, 'p', NULL, state, N_("num"),
4910 + N_("remove <num> leading slashes from traditional diff paths"),
4911 + 0, apply_option_parse_p },
4912 + OPT_BOOL(0, "no-add", &state->no_add,
4913 + N_("ignore additions made by the patch")),
4914 + OPT_BOOL(0, "stat", &state->diffstat,
4915 + N_("instead of applying the patch, output diffstat for the input")),
4916 + OPT_NOOP_NOARG(0, "allow-binary-replacement"),
4917 + OPT_NOOP_NOARG(0, "binary"),
4918 + OPT_BOOL(0, "numstat", &state->numstat,
4919 + N_("show number of added and deleted lines in decimal notation")),
4920 + OPT_BOOL(0, "summary", &state->summary,
4921 + N_("instead of applying the patch, output a summary for the input")),
4922 + OPT_BOOL(0, "check", &state->check,
4923 + N_("instead of applying the patch, see if the patch is applicable")),
4924 + OPT_BOOL(0, "index", &state->check_index,
4925 + N_("make sure the patch is applicable to the current index")),
4926 + OPT_BOOL(0, "cached", &state->cached,
4927 + N_("apply a patch without touching the working tree")),
4928 + OPT_BOOL(0, "unsafe-paths", &state->unsafe_paths,
4929 + N_("accept a patch that touches outside the working area")),
4930 + OPT_BOOL(0, "apply", force_apply,
4931 + N_("also apply the patch (use with --stat/--summary/--check)")),
4932 + OPT_BOOL('3', "3way", &state->threeway,
4933 + N_( "attempt three-way merge if a patch does not apply")),
4934 + OPT_FILENAME(0, "build-fake-ancestor", &state->fake_ancestor,
4935 + N_("build a temporary index based on embedded index information")),
4936 + /* Think twice before adding "--nul" synonym to this */
4937 + OPT_SET_INT('z', NULL, &state->line_termination,
4938 + N_("paths are separated with NUL character"), '\0'),
4939 + OPT_INTEGER('C', NULL, &state->p_context,
4940 + N_("ensure at least <n> lines of context match")),
4941 + { OPTION_CALLBACK, 0, "whitespace", state, N_("action"),
4942 + N_("detect new or modified lines that have whitespace errors"),
4943 + 0, apply_option_parse_whitespace },
4944 + { OPTION_CALLBACK, 0, "ignore-space-change", state, NULL,
4945 + N_("ignore changes in whitespace when finding context"),
4946 + PARSE_OPT_NOARG, apply_option_parse_space_change },
4947 + { OPTION_CALLBACK, 0, "ignore-whitespace", state, NULL,
4948 + N_("ignore changes in whitespace when finding context"),
4949 + PARSE_OPT_NOARG, apply_option_parse_space_change },
4950 + OPT_BOOL('R', "reverse", &state->apply_in_reverse,
4951 + N_("apply the patch in reverse")),
4952 + OPT_BOOL(0, "unidiff-zero", &state->unidiff_zero,
4953 + N_("don't expect at least one line of context")),
4954 + OPT_BOOL(0, "reject", &state->apply_with_reject,
4955 + N_("leave the rejected hunks in corresponding *.rej files")),
4956 + OPT_BOOL(0, "allow-overlap", &state->allow_overlap,
4957 + N_("allow overlapping hunks")),
4958 + OPT__VERBOSE(&state->apply_verbosity, N_("be verbose")),
4959 + OPT_BIT(0, "inaccurate-eof", options,
4960 + N_("tolerate incorrectly detected missing new-line at the end of file"),
4961 + APPLY_OPT_INACCURATE_EOF),
4962 + OPT_BIT(0, "recount", options,
4963 + N_("do not trust the line counts in the hunk headers"),
4964 + APPLY_OPT_RECOUNT),
4965 + { OPTION_CALLBACK, 0, "directory", state, N_("root"),
4966 + N_("prepend <root> to all filenames"),
4967 + 0, apply_option_parse_directory },
4968 + OPT_END()
4969 + };
4970 +
4971 + return parse_options(argc, argv, state->prefix, builtin_apply_options, apply_usage, 0);
4972 +}
apply.h
+4 -14
@@ -111,20 +111,10 @@ struct apply_state {
111 int applied_after_fixing_ws;
112 };
113
114 -extern int apply_option_parse_exclude(const struct option *opt,
115 - const char *arg, int unset);
116 -extern int apply_option_parse_include(const struct option *opt,
117 - const char *arg, int unset);
118 -extern int apply_option_parse_p(const struct option *opt,
119 - const char *arg,
120 - int unset);
121 -extern int apply_option_parse_whitespace(const struct option *opt,
122 - const char *arg, int unset);
123 -extern int apply_option_parse_directory(const struct option *opt,
124 - const char *arg, int unset);
125 -extern int apply_option_parse_space_change(const struct option *opt,
126 - const char *arg, int unset);
127 -
114 +extern int apply_parse_options(int argc, const char **argv,
115 + struct apply_state *state,
116 + int *force_apply, int *options,
117 + const char * const *apply_usage);
118 extern int init_apply_state(struct apply_state *state,
119 const char *prefix,
120 struct lock_file *lock_file);
builtin/apply.c
+3 -71
@@ -18,80 +18,12 @@ int cmd_apply(int argc, const char **argv, const char *prefix)
18 int ret;
19 struct apply_state state;
20
21 - struct option builtin_apply_options[] = {
22 - { OPTION_CALLBACK, 0, "exclude", &state, N_("path"),
23 - N_("don't apply changes matching the given path"),
24 - 0, apply_option_parse_exclude },
25 - { OPTION_CALLBACK, 0, "include", &state, N_("path"),
26 - N_("apply changes matching the given path"),
27 - 0, apply_option_parse_include },
28 - { OPTION_CALLBACK, 'p', NULL, &state, N_("num"),
29 - N_("remove <num> leading slashes from traditional diff paths"),
30 - 0, apply_option_parse_p },
31 - OPT_BOOL(0, "no-add", &state.no_add,
32 - N_("ignore additions made by the patch")),
33 - OPT_BOOL(0, "stat", &state.diffstat,
34 - N_("instead of applying the patch, output diffstat for the input")),
35 - OPT_NOOP_NOARG(0, "allow-binary-replacement"),
36 - OPT_NOOP_NOARG(0, "binary"),
37 - OPT_BOOL(0, "numstat", &state.numstat,
38 - N_("show number of added and deleted lines in decimal notation")),
39 - OPT_BOOL(0, "summary", &state.summary,
40 - N_("instead of applying the patch, output a summary for the input")),
41 - OPT_BOOL(0, "check", &state.check,
42 - N_("instead of applying the patch, see if the patch is applicable")),
43 - OPT_BOOL(0, "index", &state.check_index,
44 - N_("make sure the patch is applicable to the current index")),
45 - OPT_BOOL(0, "cached", &state.cached,
46 - N_("apply a patch without touching the working tree")),
47 - OPT_BOOL(0, "unsafe-paths", &state.unsafe_paths,
48 - N_("accept a patch that touches outside the working area")),
49 - OPT_BOOL(0, "apply", &force_apply,
50 - N_("also apply the patch (use with --stat/--summary/--check)")),
51 - OPT_BOOL('3', "3way", &state.threeway,
52 - N_( "attempt three-way merge if a patch does not apply")),
53 - OPT_FILENAME(0, "build-fake-ancestor", &state.fake_ancestor,
54 - N_("build a temporary index based on embedded index information")),
55 - /* Think twice before adding "--nul" synonym to this */
56 - OPT_SET_INT('z', NULL, &state.line_termination,
57 - N_("paths are separated with NUL character"), '\0'),
58 - OPT_INTEGER('C', NULL, &state.p_context,
59 - N_("ensure at least <n> lines of context match")),
60 - { OPTION_CALLBACK, 0, "whitespace", &state, N_("action"),
61 - N_("detect new or modified lines that have whitespace errors"),
62 - 0, apply_option_parse_whitespace },
63 - { OPTION_CALLBACK, 0, "ignore-space-change", &state, NULL,
64 - N_("ignore changes in whitespace when finding context"),
65 - PARSE_OPT_NOARG, apply_option_parse_space_change },
66 - { OPTION_CALLBACK, 0, "ignore-whitespace", &state, NULL,
67 - N_("ignore changes in whitespace when finding context"),
68 - PARSE_OPT_NOARG, apply_option_parse_space_change },
69 - OPT_BOOL('R', "reverse", &state.apply_in_reverse,
70 - N_("apply the patch in reverse")),
71 - OPT_BOOL(0, "unidiff-zero", &state.unidiff_zero,
72 - N_("don't expect at least one line of context")),
73 - OPT_BOOL(0, "reject", &state.apply_with_reject,
74 - N_("leave the rejected hunks in corresponding *.rej files")),
75 - OPT_BOOL(0, "allow-overlap", &state.allow_overlap,
76 - N_("allow overlapping hunks")),
77 - OPT__VERBOSE(&state.apply_verbosity, N_("be verbose")),
78 - OPT_BIT(0, "inaccurate-eof", &options,
79 - N_("tolerate incorrectly detected missing new-line at the end of file"),
80 - APPLY_OPT_INACCURATE_EOF),
81 - OPT_BIT(0, "recount", &options,
82 - N_("do not trust the line counts in the hunk headers"),
83 - APPLY_OPT_RECOUNT),
84 - { OPTION_CALLBACK, 0, "directory", &state, N_("root"),
85 - N_("prepend <root> to all filenames"),
86 - 0, apply_option_parse_directory },
87 - OPT_END()
88 - };
89 -
21 if (init_apply_state(&state, prefix, &lock_file))
22 exit(128);
23
93 - argc = parse_options(argc, argv, state.prefix, builtin_apply_options,
94 - apply_usage, 0);
24 + argc = apply_parse_options(argc, argv,
25 + &state, &force_apply, &options,
26 + apply_usage);
27
28 if (check_apply_state(&state, force_apply))
29 exit(128);