Git fork
at reftables-rust 318 lines 7.0 kB view raw
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 19int 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 40int 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 50int parse_opt_color_flag_cb(const struct option *opt, const char *arg, 51 int unset) 52{ 53 enum git_colorbool value; 54 55 if (!arg) 56 arg = unset ? "never" : (const char *)opt->defval; 57 value = git_config_colorbool(NULL, arg); 58 if (value == GIT_COLOR_UNKNOWN) 59 return error(_("option `%s' expects \"always\", \"auto\", or \"never\""), 60 opt->long_name); 61 *(int *)opt->value = value; 62 return 0; 63} 64 65int 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 89int 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 107int 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 126int 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 142int 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(the_hash_algo)); 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 159int 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 169static 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 178struct 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 185struct 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 199int 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 215int 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 231int 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 */ 241static 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 */ 271int 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 */ 292int 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 305int 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}