git

Форк
0
/
parse-options-cb.c 
318 строк · 6.8 Кб
1
#define USE_THE_REPOSITORY_VARIABLE
2

3
#include "git-compat-util.h"
4
#include "parse-options.h"
5
#include "branch.h"
6
#include "commit.h"
7
#include "color.h"
8
#include "date.h"
9
#include "environment.h"
10
#include "gettext.h"
11
#include "object-name.h"
12
#include "setup.h"
13
#include "string-list.h"
14
#include "strvec.h"
15
#include "oid-array.h"
16

17
/*----- some often used options -----*/
18

19
int parse_opt_abbrev_cb(const struct option *opt, const char *arg, int unset)
20
{
21
	int v;
22

23
	if (!arg) {
24
		v = unset ? 0 : DEFAULT_ABBREV;
25
	} else {
26
		if (!*arg)
27
			return error(_("option `%s' expects a numerical value"),
28
				     opt->long_name);
29
		v = strtol(arg, (char **)&arg, 10);
30
		if (*arg)
31
			return error(_("option `%s' expects a numerical value"),
32
				     opt->long_name);
33
		if (v && v < MINIMUM_ABBREV)
34
			v = MINIMUM_ABBREV;
35
	}
36
	*(int *)(opt->value) = v;
37
	return 0;
38
}
39

40
int parse_opt_expiry_date_cb(const struct option *opt, const char *arg,
41
			     int unset)
42
{
43
	if (unset)
44
		arg = "never";
45
	if (parse_expiry_date(arg, (timestamp_t *)opt->value))
46
		die(_("malformed expiration date '%s'"), arg);
47
	return 0;
48
}
49

50
int parse_opt_color_flag_cb(const struct option *opt, const char *arg,
51
			    int unset)
52
{
53
	int value;
54

55
	if (!arg)
56
		arg = unset ? "never" : (const char *)opt->defval;
57
	value = git_config_colorbool(NULL, arg);
58
	if (value < 0)
59
		return error(_("option `%s' expects \"always\", \"auto\", or \"never\""),
60
			     opt->long_name);
61
	*(int *)opt->value = value;
62
	return 0;
63
}
64

65
int parse_opt_verbosity_cb(const struct option *opt, const char *arg,
66
			   int unset)
67
{
68
	int *target = opt->value;
69

70
	BUG_ON_OPT_ARG(arg);
71

72
	if (unset)
73
		/* --no-quiet, --no-verbose */
74
		*target = 0;
75
	else if (opt->short_name == 'v') {
76
		if (*target >= 0)
77
			(*target)++;
78
		else
79
			*target = 1;
80
	} else {
81
		if (*target <= 0)
82
			(*target)--;
83
		else
84
			*target = -1;
85
	}
86
	return 0;
87
}
88

89
int parse_opt_commits(const struct option *opt, const char *arg, int unset)
90
{
91
	struct object_id oid;
92
	struct commit *commit;
93

94
	BUG_ON_OPT_NEG(unset);
95

96
	if (!arg)
97
		return -1;
98
	if (repo_get_oid(the_repository, arg, &oid))
99
		return error("malformed object name %s", arg);
100
	commit = lookup_commit_reference(the_repository, &oid);
101
	if (!commit)
102
		return error("no such commit %s", arg);
103
	commit_list_insert(commit, opt->value);
104
	return 0;
105
}
106

107
int parse_opt_commit(const struct option *opt, const char *arg, int unset)
108
{
109
	struct object_id oid;
110
	struct commit *commit;
111
	struct commit **target = opt->value;
112

113
	BUG_ON_OPT_NEG(unset);
114

115
	if (!arg)
116
		return -1;
117
	if (repo_get_oid(the_repository, arg, &oid))
118
		return error("malformed object name %s", arg);
119
	commit = lookup_commit_reference(the_repository, &oid);
120
	if (!commit)
121
		return error("no such commit %s", arg);
122
	*target = commit;
123
	return 0;
124
}
125

126
int parse_opt_object_name(const struct option *opt, const char *arg, int unset)
127
{
128
	struct object_id oid;
129

130
	if (unset) {
131
		oid_array_clear(opt->value);
132
		return 0;
133
	}
134
	if (!arg)
135
		return -1;
136
	if (repo_get_oid(the_repository, arg, &oid))
137
		return error(_("malformed object name '%s'"), arg);
138
	oid_array_append(opt->value, &oid);
139
	return 0;
140
}
141

142
int parse_opt_object_id(const struct option *opt, const char *arg, int unset)
143
{
144
	struct object_id oid;
145
	struct object_id *target = opt->value;
146

147
	if (unset) {
148
		oidcpy(target, null_oid());
149
		return 0;
150
	}
151
	if (!arg)
152
		return -1;
153
	if (repo_get_oid(the_repository, arg, &oid))
154
		return error(_("malformed object name '%s'"), arg);
155
	*target = oid;
156
	return 0;
157
}
158

159
int parse_opt_tertiary(const struct option *opt, const char *arg, int unset)
160
{
161
	int *target = opt->value;
162

163
	BUG_ON_OPT_ARG(arg);
164

165
	*target = unset ? 2 : 1;
166
	return 0;
167
}
168

169
static size_t parse_options_count(const struct option *opt)
170
{
171
	size_t n = 0;
172

173
	for (; opt && opt->type != OPTION_END; opt++)
174
		n++;
175
	return n;
176
}
177

178
struct option *parse_options_dup(const struct option *o)
179
{
180
	struct option no_options[] = { OPT_END() };
181

182
	return parse_options_concat(o, no_options);
183
}
184

185
struct option *parse_options_concat(const struct option *a,
186
				    const struct option *b)
187
{
188
	struct option *ret;
189
	size_t a_len = parse_options_count(a);
190
	size_t b_len = parse_options_count(b);
191

192
	ALLOC_ARRAY(ret, st_add3(a_len, b_len, 1));
193
	COPY_ARRAY(ret, a, a_len);
194
	COPY_ARRAY(ret + a_len, b, b_len + 1); /* + 1 for final OPTION_END */
195

196
	return ret;
197
}
198

199
int parse_opt_string_list(const struct option *opt, const char *arg, int unset)
200
{
201
	struct string_list *v = opt->value;
202

203
	if (unset) {
204
		string_list_clear(v, 0);
205
		return 0;
206
	}
207

208
	if (!arg)
209
		return -1;
210

211
	string_list_append(v, arg);
212
	return 0;
213
}
214

215
int parse_opt_strvec(const struct option *opt, const char *arg, int unset)
216
{
217
	struct strvec *v = opt->value;
218

219
	if (unset) {
220
		strvec_clear(v);
221
		return 0;
222
	}
223

224
	if (!arg)
225
		return -1;
226

227
	strvec_push(v, arg);
228
	return 0;
229
}
230

231
int parse_opt_noop_cb(const struct option *opt UNUSED,
232
		      const char *arg UNUSED,
233
		      int unset UNUSED)
234
{
235
	return 0;
236
}
237

238
/**
239
 * Recreates the command-line option in the strbuf.
240
 */
241
static int recreate_opt(struct strbuf *sb, const struct option *opt,
242
		const char *arg, int unset)
243
{
244
	strbuf_reset(sb);
245

246
	if (opt->long_name) {
247
		strbuf_addstr(sb, unset ? "--no-" : "--");
248
		strbuf_addstr(sb, opt->long_name);
249
		if (arg) {
250
			strbuf_addch(sb, '=');
251
			strbuf_addstr(sb, arg);
252
		}
253
	} else if (opt->short_name && !unset) {
254
		strbuf_addch(sb, '-');
255
		strbuf_addch(sb, opt->short_name);
256
		if (arg)
257
			strbuf_addstr(sb, arg);
258
	} else
259
		return -1;
260

261
	return 0;
262
}
263

264
/**
265
 * For an option opt, recreates the command-line option in opt->value which
266
 * must be an char* initialized to NULL. This is useful when we need to pass
267
 * the command-line option to another command. Since any previous value will be
268
 * overwritten, this callback should only be used for options where the last
269
 * one wins.
270
 */
271
int parse_opt_passthru(const struct option *opt, const char *arg, int unset)
272
{
273
	static struct strbuf sb = STRBUF_INIT;
274
	char **opt_value = opt->value;
275

276
	if (recreate_opt(&sb, opt, arg, unset) < 0)
277
		return -1;
278

279
	free(*opt_value);
280

281
	*opt_value = strbuf_detach(&sb, NULL);
282

283
	return 0;
284
}
285

286
/**
287
 * For an option opt, recreate the command-line option, appending it to
288
 * opt->value which must be a strvec. This is useful when we need to pass
289
 * the command-line option, which can be specified multiple times, to another
290
 * command.
291
 */
292
int parse_opt_passthru_argv(const struct option *opt, const char *arg, int unset)
293
{
294
	static struct strbuf sb = STRBUF_INIT;
295
	struct strvec *opt_value = opt->value;
296

297
	if (recreate_opt(&sb, opt, arg, unset) < 0)
298
		return -1;
299

300
	strvec_push(opt_value, sb.buf);
301

302
	return 0;
303
}
304

305
int parse_opt_tracking_mode(const struct option *opt, const char *arg, int unset)
306
{
307
	if (unset)
308
		*(enum branch_track *)opt->value = BRANCH_TRACK_NEVER;
309
	else if (!arg || !strcmp(arg, "direct"))
310
		*(enum branch_track *)opt->value = BRANCH_TRACK_EXPLICIT;
311
	else if (!strcmp(arg, "inherit"))
312
		*(enum branch_track *)opt->value = BRANCH_TRACK_INHERIT;
313
	else
314
		return error(_("option `%s' expects \"%s\" or \"%s\""),
315
			     "--track", "direct", "inherit");
316

317
	return 0;
318
}
319

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.