blob: e2f3eaed072f77d63890ec814d810199f57248d5 [file] [log] [blame]
Dmitry Ivankov06876282011-08-11 15:15:38 +06001#include "git-compat-util.h"
2#include "parse-options.h"
3#include "cache.h"
4#include "commit.h"
5#include "color.h"
6#include "string-list.h"
Paul Tanffad85c2015-06-14 16:41:49 +08007#include "argv-array.h"
Karthik Nayakb2172fd2015-07-07 21:36:08 +05308#include "sha1-array.h"
Dmitry Ivankov06876282011-08-11 15:15:38 +06009
10/*----- some often used options -----*/
11
12int parse_opt_abbrev_cb(const struct option *opt, const char *arg, int unset)
13{
14 int v;
15
16 if (!arg) {
17 v = unset ? 0 : DEFAULT_ABBREV;
18 } else {
19 v = strtol(arg, (char **)&arg, 10);
20 if (*arg)
Nguyễn Thái Ngọc Duy9440b832018-11-10 06:16:11 +010021 return error(_("option `%s' expects a numerical value"),
22 opt->long_name);
Dmitry Ivankov06876282011-08-11 15:15:38 +060023 if (v && v < MINIMUM_ABBREV)
24 v = MINIMUM_ABBREV;
25 else if (v > 40)
26 v = 40;
27 }
28 *(int *)(opt->value) = v;
29 return 0;
30}
31
Junio C Hamano27ec3942013-04-25 11:13:49 -070032int parse_opt_expiry_date_cb(const struct option *opt, const char *arg,
33 int unset)
34{
Junio C Hamano8ab5aa42018-04-21 12:13:13 +090035 if (unset)
36 arg = "never";
37 if (parse_expiry_date(arg, (timestamp_t *)opt->value))
38 die(_("malformed expiration date '%s'"), arg);
39 return 0;
Junio C Hamano27ec3942013-04-25 11:13:49 -070040}
41
Dmitry Ivankov06876282011-08-11 15:15:38 +060042int parse_opt_color_flag_cb(const struct option *opt, const char *arg,
43 int unset)
44{
45 int value;
46
47 if (!arg)
48 arg = unset ? "never" : (const char *)opt->defval;
Junio C Hamanof946b462011-08-28 21:19:16 -070049 value = git_config_colorbool(NULL, arg);
Dmitry Ivankov06876282011-08-11 15:15:38 +060050 if (value < 0)
Nguyễn Thái Ngọc Duy9440b832018-11-10 06:16:11 +010051 return error(_("option `%s' expects \"always\", \"auto\", or \"never\""),
52 opt->long_name);
Dmitry Ivankov06876282011-08-11 15:15:38 +060053 *(int *)opt->value = value;
54 return 0;
55}
56
57int parse_opt_verbosity_cb(const struct option *opt, const char *arg,
58 int unset)
59{
60 int *target = opt->value;
61
Jeff King517fe802018-11-05 01:45:42 -050062 BUG_ON_OPT_ARG(arg);
63
Dmitry Ivankov06876282011-08-11 15:15:38 +060064 if (unset)
65 /* --no-quiet, --no-verbose */
66 *target = 0;
67 else if (opt->short_name == 'v') {
68 if (*target >= 0)
69 (*target)++;
70 else
71 *target = 1;
72 } else {
73 if (*target <= 0)
74 (*target)--;
75 else
76 *target = -1;
77 }
78 return 0;
79}
80
Karthik Nayak9d306b52015-07-07 21:36:14 +053081int parse_opt_commits(const struct option *opt, const char *arg, int unset)
Dmitry Ivankov06876282011-08-11 15:15:38 +060082{
brian m. carlson9e31eaf2017-05-06 22:09:59 +000083 struct object_id oid;
Dmitry Ivankov06876282011-08-11 15:15:38 +060084 struct commit *commit;
85
Jeff King517fe802018-11-05 01:45:42 -050086 BUG_ON_OPT_NEG(unset);
87
Dmitry Ivankov06876282011-08-11 15:15:38 +060088 if (!arg)
89 return -1;
brian m. carlson9e31eaf2017-05-06 22:09:59 +000090 if (get_oid(arg, &oid))
Dmitry Ivankov06876282011-08-11 15:15:38 +060091 return error("malformed object name %s", arg);
Stefan Beller2122f672018-06-28 18:21:58 -070092 commit = lookup_commit_reference(the_repository, &oid);
Dmitry Ivankov06876282011-08-11 15:15:38 +060093 if (!commit)
94 return error("no such commit %s", arg);
95 commit_list_insert(commit, opt->value);
96 return 0;
97}
98
Karthik Nayakb2172fd2015-07-07 21:36:08 +053099int parse_opt_object_name(const struct option *opt, const char *arg, int unset)
100{
brian m. carlson9e1d7082017-03-26 16:01:31 +0000101 struct object_id oid;
Karthik Nayakb2172fd2015-07-07 21:36:08 +0530102
103 if (unset) {
brian m. carlson910650d2017-03-31 01:40:00 +0000104 oid_array_clear(opt->value);
Karthik Nayakb2172fd2015-07-07 21:36:08 +0530105 return 0;
106 }
107 if (!arg)
108 return -1;
brian m. carlson9e1d7082017-03-26 16:01:31 +0000109 if (get_oid(arg, &oid))
Karthik Nayakb2172fd2015-07-07 21:36:08 +0530110 return error(_("malformed object name '%s'"), arg);
brian m. carlson910650d2017-03-31 01:40:00 +0000111 oid_array_append(opt->value, &oid);
Karthik Nayakb2172fd2015-07-07 21:36:08 +0530112 return 0;
113}
114
Dmitry Ivankov06876282011-08-11 15:15:38 +0600115int parse_opt_tertiary(const struct option *opt, const char *arg, int unset)
116{
117 int *target = opt->value;
Jeff King517fe802018-11-05 01:45:42 -0500118
119 BUG_ON_OPT_ARG(arg);
120
Dmitry Ivankov06876282011-08-11 15:15:38 +0600121 *target = unset ? 2 : 1;
122 return 0;
123}
124
Jeff King023ff392016-07-05 16:44:47 -0400125struct option *parse_options_concat(struct option *a, struct option *b)
Dmitry Ivankov06876282011-08-11 15:15:38 +0600126{
Jeff King023ff392016-07-05 16:44:47 -0400127 struct option *ret;
128 size_t i, a_len = 0, b_len = 0;
Dmitry Ivankov06876282011-08-11 15:15:38 +0600129
Jeff King023ff392016-07-05 16:44:47 -0400130 for (i = 0; a[i].type != OPTION_END; i++)
131 a_len++;
132 for (i = 0; b[i].type != OPTION_END; i++)
133 b_len++;
134
135 ALLOC_ARRAY(ret, st_add3(a_len, b_len, 1));
136 for (i = 0; i < a_len; i++)
137 ret[i] = a[i];
138 for (i = 0; i < b_len; i++)
139 ret[a_len + i] = b[i];
140 ret[a_len + b_len] = b[b_len]; /* final OPTION_END */
141
142 return ret;
Dmitry Ivankov06876282011-08-11 15:15:38 +0600143}
144
145int parse_opt_string_list(const struct option *opt, const char *arg, int unset)
146{
147 struct string_list *v = opt->value;
148
149 if (unset) {
150 string_list_clear(v, 0);
151 return 0;
152 }
153
154 if (!arg)
155 return -1;
156
Jeff King7a7a5172016-06-13 01:39:12 -0400157 string_list_append(v, arg);
Dmitry Ivankov06876282011-08-11 15:15:38 +0600158 return 0;
159}
René Scharfe6acec032011-09-28 19:44:30 +0200160
161int parse_opt_noop_cb(const struct option *opt, const char *arg, int unset)
162{
163 return 0;
164}
Paul Tan6b3ee182015-06-14 16:41:48 +0800165
166/**
Michael Haggertyce564eb2016-09-05 11:44:52 +0200167 * Report that the option is unknown, so that other code can handle
168 * it. This can be used as a callback together with
169 * OPTION_LOWLEVEL_CALLBACK to allow an option to be documented in the
170 * "-h" output even if it's not being handled directly by
171 * parse_options().
172 */
173int parse_opt_unknown_cb(const struct option *opt, const char *arg, int unset)
174{
175 return -2;
176}
177
178/**
Paul Tan6b3ee182015-06-14 16:41:48 +0800179 * Recreates the command-line option in the strbuf.
180 */
181static int recreate_opt(struct strbuf *sb, const struct option *opt,
182 const char *arg, int unset)
183{
184 strbuf_reset(sb);
185
186 if (opt->long_name) {
187 strbuf_addstr(sb, unset ? "--no-" : "--");
188 strbuf_addstr(sb, opt->long_name);
189 if (arg) {
190 strbuf_addch(sb, '=');
191 strbuf_addstr(sb, arg);
192 }
193 } else if (opt->short_name && !unset) {
194 strbuf_addch(sb, '-');
195 strbuf_addch(sb, opt->short_name);
196 if (arg)
197 strbuf_addstr(sb, arg);
198 } else
199 return -1;
200
201 return 0;
202}
203
204/**
205 * For an option opt, recreates the command-line option in opt->value which
206 * must be an char* initialized to NULL. This is useful when we need to pass
207 * the command-line option to another command. Since any previous value will be
208 * overwritten, this callback should only be used for options where the last
209 * one wins.
210 */
211int parse_opt_passthru(const struct option *opt, const char *arg, int unset)
212{
213 static struct strbuf sb = STRBUF_INIT;
214 char **opt_value = opt->value;
215
216 if (recreate_opt(&sb, opt, arg, unset) < 0)
217 return -1;
218
René Scharfe39ea59a2016-10-08 16:14:57 +0200219 free(*opt_value);
Paul Tan6b3ee182015-06-14 16:41:48 +0800220
221 *opt_value = strbuf_detach(&sb, NULL);
222
223 return 0;
224}
Paul Tanffad85c2015-06-14 16:41:49 +0800225
226/**
227 * For an option opt, recreate the command-line option, appending it to
228 * opt->value which must be a argv_array. This is useful when we need to pass
229 * the command-line option, which can be specified multiple times, to another
230 * command.
231 */
232int parse_opt_passthru_argv(const struct option *opt, const char *arg, int unset)
233{
234 static struct strbuf sb = STRBUF_INIT;
235 struct argv_array *opt_value = opt->value;
236
237 if (recreate_opt(&sb, opt, arg, unset) < 0)
238 return -1;
239
240 argv_array_push(opt_value, sb.buf);
241
242 return 0;
243}