Merge branch 'jk/unused-parameter-fixes'
authorJunio C Hamano <gitster@pobox.com>
Sun, 18 Nov 2018 09:23:53 +0000 (18:23 +0900)
committerJunio C Hamano <gitster@pobox.com>
Sun, 18 Nov 2018 09:23:53 +0000 (18:23 +0900)
Various functions have been audited for "-Wunused-parameter" warnings
and bugs in them got fixed.

* jk/unused-parameter-fixes:
midx: double-check large object write loop
assert NOARG/NONEG behavior of parse-options callbacks
parse-options: drop OPT_DATE()
apply: return -1 from option callback instead of calling exit(1)
cat-file: report an error on multiple --batch options
tag: mark "--message" option with NONEG
show-branch: mark --reflog option as NONEG
format-patch: mark "--no-numbered" option with NONEG
status: mark --find-renames option with NONEG
cat-file: mark batch options with NONEG
pack-objects: mark index-version option as NONEG
ls-files: mark exclude options as NONEG
am: handle --no-patch-format option
apply: mark include/exclude options as NONEG

30 files changed:
Documentation/technical/api-parse-options.txt
apply.c
builtin/am.c
builtin/blame.c
builtin/cat-file.c
builtin/checkout-index.c
builtin/clean.c
builtin/commit.c
builtin/fetch.c
builtin/grep.c
builtin/init-db.c
builtin/interpret-trailers.c
builtin/log.c
builtin/ls-files.c
builtin/merge-file.c
builtin/merge.c
builtin/notes.c
builtin/pack-objects.c
builtin/read-tree.c
builtin/rebase.c
builtin/show-branch.c
builtin/show-ref.c
builtin/tag.c
builtin/update-index.c
midx.c
parse-options-cb.c
parse-options.h
ref-filter.c
t/helper/test-parse-options.c
t/t0040-parse-options.sh
index 829b5581105468d4d3b457e60b10cdbdf317fbbc..2b036d7838ef906153a29cf0e17d57a1dbe93109 100644 (file)
@@ -183,10 +183,6 @@ There are some macros to easily define options:
        scale the provided value by 1024, 1024^2 or 1024^3 respectively.
        The scaled value is put into `unsigned_long_var`.
 
-`OPT_DATE(short, long, &timestamp_t_var, description)`::
-       Introduce an option with date argument, see `approxidate()`.
-       The timestamp is put into `timestamp_t_var`.
-
 `OPT_EXPIRY_DATE(short, long, &timestamp_t_var, description)`::
        Introduce an option with expiry date argument, see `parse_expiry_date()`.
        The timestamp is put into `timestamp_t_var`.
diff --git a/apply.c b/apply.c
index 073d5f04512ac6febc2949040f53ef273433f3c0..3746310cefae7ff8127cc033e0c11b3eb43eecd0 100644 (file)
--- a/apply.c
+++ b/apply.c
@@ -4772,6 +4772,9 @@ static int apply_option_parse_exclude(const struct option *opt,
                                      const char *arg, int unset)
 {
        struct apply_state *state = opt->value;
+
+       BUG_ON_OPT_NEG(unset);
+
        add_name_limit(state, arg, 1);
        return 0;
 }
@@ -4780,6 +4783,9 @@ static int apply_option_parse_include(const struct option *opt,
                                      const char *arg, int unset)
 {
        struct apply_state *state = opt->value;
+
+       BUG_ON_OPT_NEG(unset);
+
        add_name_limit(state, arg, 0);
        state->has_include = 1;
        return 0;
@@ -4790,6 +4796,9 @@ static int apply_option_parse_p(const struct option *opt,
                                int unset)
 {
        struct apply_state *state = opt->value;
+
+       BUG_ON_OPT_NEG(unset);
+
        state->p_value = atoi(arg);
        state->p_value_known = 1;
        return 0;
@@ -4799,6 +4808,9 @@ static int apply_option_parse_space_change(const struct option *opt,
                                           const char *arg, int unset)
 {
        struct apply_state *state = opt->value;
+
+       BUG_ON_OPT_ARG(arg);
+
        if (unset)
                state->ws_ignore_action = ignore_ws_none;
        else
@@ -4810,9 +4822,12 @@ static int apply_option_parse_whitespace(const struct option *opt,
                                         const char *arg, int unset)
 {
        struct apply_state *state = opt->value;
+
+       BUG_ON_OPT_NEG(unset);
+
        state->whitespace_option = arg;
        if (parse_whitespace_option(state, arg))
-               exit(1);
+               return -1;
        return 0;
 }
 
@@ -4820,6 +4835,9 @@ static int apply_option_parse_directory(const struct option *opt,
                                        const char *arg, int unset)
 {
        struct apply_state *state = opt->value;
+
+       BUG_ON_OPT_NEG(unset);
+
        strbuf_reset(&state->root);
        strbuf_addstr(&state->root, arg);
        strbuf_complete(&state->root, '/');
@@ -4939,10 +4957,10 @@ int apply_parse_options(int argc, const char **argv,
        struct option builtin_apply_options[] = {
                { OPTION_CALLBACK, 0, "exclude", state, N_("path"),
                        N_("don't apply changes matching the given path"),
-                       0, apply_option_parse_exclude },
+                       PARSE_OPT_NONEG, apply_option_parse_exclude },
                { OPTION_CALLBACK, 0, "include", state, N_("path"),
                        N_("apply changes matching the given path"),
-                       0, apply_option_parse_include },
+                       PARSE_OPT_NONEG, apply_option_parse_include },
                { OPTION_CALLBACK, 'p', NULL, state, N_("num"),
                        N_("remove <num> leading slashes from traditional diff paths"),
                        0, apply_option_parse_p },
index dc576a33728f5c2264acf66fcbe3243284144781..8f27f3375b1e92f2ef026e0a1530ca8b6b3235bf 100644 (file)
@@ -2113,7 +2113,9 @@ static int parse_opt_patchformat(const struct option *opt, const char *arg, int
 {
        int *opt_value = opt->value;
 
-       if (!strcmp(arg, "mbox"))
+       if (unset)
+               *opt_value = PATCH_FORMAT_UNKNOWN;
+       else if (!strcmp(arg, "mbox"))
                *opt_value = PATCH_FORMAT_MBOX;
        else if (!strcmp(arg, "stgit"))
                *opt_value = PATCH_FORMAT_STGIT;
index a443af9ee9dad5ec20de7e75640947c221e7aa6a..06a7163ffe269cd43dc783c81ca6ac71b91b3614 100644 (file)
@@ -732,6 +732,8 @@ static int blame_copy_callback(const struct option *option, const char *arg, int
 {
        int *opt = option->value;
 
+       BUG_ON_OPT_NEG(unset);
+
        /*
         * -C enables copy from removed files;
         * -C -C enables copy from existing files, but only
@@ -754,6 +756,8 @@ static int blame_move_callback(const struct option *option, const char *arg, int
 {
        int *opt = option->value;
 
+       BUG_ON_OPT_NEG(unset);
+
        *opt |= PICKAXE_BLAME_MOVE;
 
        if (arg)
index 0d403eb77d37d3b409d7d8ef030c12b91fe63da6..657fe926e2ae884012a8987e7a5753f4277384d7 100644 (file)
@@ -603,8 +603,10 @@ static int batch_option_callback(const struct option *opt,
 {
        struct batch_options *bo = opt->value;
 
+       BUG_ON_OPT_NEG(unset);
+
        if (bo->enabled) {
-               return 1;
+               return error(_("only one batch option may be specified"));
        }
 
        bo->enabled = 1;
@@ -639,10 +641,12 @@ int cmd_cat_file(int argc, const char **argv, const char *prefix)
                OPT_BOOL(0, "buffer", &batch.buffer_output, N_("buffer --batch output")),
                { OPTION_CALLBACK, 0, "batch", &batch, "format",
                        N_("show info and content of objects fed from the standard input"),
-                       PARSE_OPT_OPTARG, batch_option_callback },
+                       PARSE_OPT_OPTARG | PARSE_OPT_NONEG,
+                       batch_option_callback },
                { OPTION_CALLBACK, 0, "batch-check", &batch, "format",
                        N_("show info about objects fed from the standard input"),
-                       PARSE_OPT_OPTARG, batch_option_callback },
+                       PARSE_OPT_OPTARG | PARSE_OPT_NONEG,
+                       batch_option_callback },
                OPT_BOOL(0, "follow-symlinks", &batch.follow_symlinks,
                         N_("follow in-tree symlinks (used with --batch or --batch-check)")),
                OPT_BOOL(0, "batch-all-objects", &batch.all_objects,
index 88b86c8d9f5a0ea9c49b42e891082203b80a977f..eb74774cbc9d6bd6acf1b7fe2f31b8e80e461a12 100644 (file)
@@ -132,6 +132,8 @@ static const char * const builtin_checkout_index_usage[] = {
 static int option_parse_stage(const struct option *opt,
                              const char *arg, int unset)
 {
+       BUG_ON_OPT_NEG(unset);
+
        if (!strcmp(arg, "all")) {
                to_tempfile = 1;
                checkout_stage = CHECKOUT_ALL;
index 8d9a7dc20647079bc5f35b446bbbab5479abb32d..bbcdeb2d9e7f275309609a2a21a5dd4baf1cf1bd 100644 (file)
@@ -140,6 +140,7 @@ static void clean_print_color(enum color_clean ix)
 static int exclude_cb(const struct option *opt, const char *arg, int unset)
 {
        struct string_list *exclude_list = opt->value;
+       BUG_ON_OPT_NEG(unset);
        string_list_append(exclude_list, arg);
        return 0;
 }
index 96d336ec3d8044918fb260d6cf8c03296cf32ed1..c021b119bb9df106ab7a860e032ea5dd35529401 100644 (file)
@@ -161,6 +161,9 @@ static int opt_parse_m(const struct option *opt, const char *arg, int unset)
 static int opt_parse_rename_score(const struct option *opt, const char *arg, int unset)
 {
        const char **value = opt->value;
+
+       BUG_ON_OPT_NEG(unset);
+
        if (arg != NULL && *arg == '=')
                arg = arg + 1;
 
@@ -1335,7 +1338,7 @@ int cmd_status(int argc, const char **argv, const char *prefix)
                OPT_BOOL(0, "no-renames", &no_renames, N_("do not detect renames")),
                { OPTION_CALLBACK, 'M', "find-renames", &rename_score_arg,
                  N_("n"), N_("detect renames, optionally set similarity index"),
-                 PARSE_OPT_OPTARG, opt_parse_rename_score },
+                 PARSE_OPT_OPTARG | PARSE_OPT_NONEG, opt_parse_rename_score },
                OPT_END(),
        };
 
index 6ec7c07d1dc111e6370dad498bf7453b5cd2c92e..e0140327aab23654c69e7388c23a07b98b8ff913 100644 (file)
@@ -98,6 +98,8 @@ static int git_fetch_config(const char *k, const char *v, void *cb)
 
 static int parse_refmap_arg(const struct option *opt, const char *arg, int unset)
 {
+       BUG_ON_OPT_NEG(unset);
+
        /*
         * "git fetch --refmap='' origin foo"
         * can be used to tell the command not to store anywhere
index cca87cf8709aed25d0fff230a436ae7f04c1811b..71df52a333cbc756b057e93bf3d2affca8157860 100644 (file)
@@ -708,11 +708,14 @@ static int context_callback(const struct option *opt, const char *arg,
 static int file_callback(const struct option *opt, const char *arg, int unset)
 {
        struct grep_opt *grep_opt = opt->value;
-       int from_stdin = !strcmp(arg, "-");
+       int from_stdin;
        FILE *patterns;
        int lno = 0;
        struct strbuf sb = STRBUF_INIT;
 
+       BUG_ON_OPT_NEG(unset);
+
+       from_stdin = !strcmp(arg, "-");
        patterns = from_stdin ? stdin : fopen(arg, "r");
        if (!patterns)
                die_errno(_("cannot open '%s'"), arg);
@@ -733,6 +736,8 @@ static int file_callback(const struct option *opt, const char *arg, int unset)
 static int not_callback(const struct option *opt, const char *arg, int unset)
 {
        struct grep_opt *grep_opt = opt->value;
+       BUG_ON_OPT_NEG(unset);
+       BUG_ON_OPT_ARG(arg);
        append_grep_pattern(grep_opt, "--not", "command line", 0, GREP_NOT);
        return 0;
 }
@@ -740,6 +745,8 @@ static int not_callback(const struct option *opt, const char *arg, int unset)
 static int and_callback(const struct option *opt, const char *arg, int unset)
 {
        struct grep_opt *grep_opt = opt->value;
+       BUG_ON_OPT_NEG(unset);
+       BUG_ON_OPT_ARG(arg);
        append_grep_pattern(grep_opt, "--and", "command line", 0, GREP_AND);
        return 0;
 }
@@ -747,6 +754,8 @@ static int and_callback(const struct option *opt, const char *arg, int unset)
 static int open_callback(const struct option *opt, const char *arg, int unset)
 {
        struct grep_opt *grep_opt = opt->value;
+       BUG_ON_OPT_NEG(unset);
+       BUG_ON_OPT_ARG(arg);
        append_grep_pattern(grep_opt, "(", "command line", 0, GREP_OPEN_PAREN);
        return 0;
 }
@@ -754,6 +763,8 @@ static int open_callback(const struct option *opt, const char *arg, int unset)
 static int close_callback(const struct option *opt, const char *arg, int unset)
 {
        struct grep_opt *grep_opt = opt->value;
+       BUG_ON_OPT_NEG(unset);
+       BUG_ON_OPT_ARG(arg);
        append_grep_pattern(grep_opt, ")", "command line", 0, GREP_CLOSE_PAREN);
        return 0;
 }
@@ -762,6 +773,7 @@ static int pattern_callback(const struct option *opt, const char *arg,
                            int unset)
 {
        struct grep_opt *grep_opt = opt->value;
+       BUG_ON_OPT_NEG(unset);
        append_grep_pattern(grep_opt, arg, "-e option", 0, GREP_PATTERN);
        return 0;
 }
index 12ddda7e7bac51f74b2f7ca8a2b64ffe90fd8683..41faffd28db8850fb97daa52c6d481375b380504 100644 (file)
@@ -451,6 +451,7 @@ static int guess_repository_type(const char *git_dir)
 
 static int shared_callback(const struct option *opt, const char *arg, int unset)
 {
+       BUG_ON_OPT_NEG(unset);
        *((int *) opt->value) = (arg) ? git_config_perm("arg", arg) : PERM_GROUP;
        return 0;
 }
index 4b87e0dd2e8854bf940e92e3020c5e4f66e8a6bd..8ae40dec4746571cf80d2f76bbad067c33a972fa 100644 (file)
@@ -80,6 +80,8 @@ static int parse_opt_parse(const struct option *opt, const char *arg,
        v->only_trailers = 1;
        v->only_input = 1;
        v->unfold = 1;
+       BUG_ON_OPT_NEG(unset);
+       BUG_ON_OPT_ARG(arg);
        return 0;
 }
 
index 061d4fd864f3fb479e2877e3bbf25928ad1fb9d3..9f2d9872946dfd7fe527a7f3822d9be23aa5ec83 100644 (file)
@@ -107,6 +107,8 @@ static int log_line_range_callback(const struct option *option, const char *arg,
 {
        struct line_opt_callback_data *data = option->value;
 
+       BUG_ON_OPT_NEG(unset);
+
        if (!arg)
                return -1;
 
@@ -1151,6 +1153,8 @@ static int keep_subject = 0;
 
 static int keep_callback(const struct option *opt, const char *arg, int unset)
 {
+       BUG_ON_OPT_NEG(unset);
+       BUG_ON_OPT_ARG(arg);
        ((struct rev_info *)opt->value)->total = -1;
        keep_subject = 1;
        return 0;
@@ -1161,6 +1165,7 @@ static int subject_prefix = 0;
 static int subject_prefix_callback(const struct option *opt, const char *arg,
                            int unset)
 {
+       BUG_ON_OPT_NEG(unset);
        subject_prefix = 1;
        ((struct rev_info *)opt->value)->subject_prefix = arg;
        return 0;
@@ -1168,6 +1173,8 @@ static int subject_prefix_callback(const struct option *opt, const char *arg,
 
 static int rfc_callback(const struct option *opt, const char *arg, int unset)
 {
+       BUG_ON_OPT_NEG(unset);
+       BUG_ON_OPT_ARG(arg);
        return subject_prefix_callback(opt, "RFC PATCH", unset);
 }
 
@@ -1176,6 +1183,7 @@ static int numbered_cmdline_opt = 0;
 static int numbered_callback(const struct option *opt, const char *arg,
                             int unset)
 {
+       BUG_ON_OPT_ARG(arg);
        *(int *)opt->value = numbered_cmdline_opt = unset ? 0 : 1;
        if (unset)
                auto_number =  0;
@@ -1185,6 +1193,7 @@ static int numbered_callback(const struct option *opt, const char *arg,
 static int no_numbered_callback(const struct option *opt, const char *arg,
                                int unset)
 {
+       BUG_ON_OPT_NEG(unset);
        return numbered_callback(opt, arg, 1);
 }
 
@@ -1192,6 +1201,7 @@ static int output_directory_callback(const struct option *opt, const char *arg,
                              int unset)
 {
        const char **dir = (const char **)opt->value;
+       BUG_ON_OPT_NEG(unset);
        if (*dir)
                die(_("Two output directories?"));
        *dir = arg;
@@ -1508,7 +1518,7 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)
                            PARSE_OPT_NOARG, numbered_callback },
                { OPTION_CALLBACK, 'N', "no-numbered", &numbered, NULL,
                            N_("use [PATCH] even with multiple patches"),
-                           PARSE_OPT_NOARG, no_numbered_callback },
+                           PARSE_OPT_NOARG | PARSE_OPT_NONEG, no_numbered_callback },
                OPT_BOOL('s', "signoff", &do_signoff, N_("add Signed-off-by:")),
                OPT_BOOL(0, "stdout", &use_stdout,
                            N_("print patches to standard out")),
index 7f9919a36234f603ffe76d7324fafc7f5872d404..c70a9c71588a76b2ef04689fc6cd805cee4ae0b8 100644 (file)
@@ -475,6 +475,8 @@ static int option_parse_exclude(const struct option *opt,
 {
        struct string_list *exclude_list = opt->value;
 
+       BUG_ON_OPT_NEG(unset);
+
        exc_given = 1;
        string_list_append(exclude_list, arg);
 
@@ -486,6 +488,8 @@ static int option_parse_exclude_from(const struct option *opt,
 {
        struct dir_struct *dir = opt->value;
 
+       BUG_ON_OPT_NEG(unset);
+
        exc_given = 1;
        add_excludes_from_file(dir, arg);
 
@@ -497,6 +501,9 @@ static int option_parse_exclude_standard(const struct option *opt,
 {
        struct dir_struct *dir = opt->value;
 
+       BUG_ON_OPT_NEG(unset);
+       BUG_ON_OPT_ARG(arg);
+
        exc_given = 1;
        setup_standard_excludes(dir);
 
@@ -548,15 +555,16 @@ int cmd_ls_files(int argc, const char **argv, const char *cmd_prefix)
                            N_("show resolve-undo information")),
                { OPTION_CALLBACK, 'x', "exclude", &exclude_list, N_("pattern"),
                        N_("skip files matching pattern"),
-                       0, option_parse_exclude },
+                       PARSE_OPT_NONEG, option_parse_exclude },
                { OPTION_CALLBACK, 'X', "exclude-from", &dir, N_("file"),
                        N_("exclude patterns are read from <file>"),
-                       0, option_parse_exclude_from },
+                       PARSE_OPT_NONEG, option_parse_exclude_from },
                OPT_STRING(0, "exclude-per-directory", &dir.exclude_per_dir, N_("file"),
                        N_("read additional per-directory exclude patterns in <file>")),
                { OPTION_CALLBACK, 0, "exclude-standard", &dir, NULL,
                        N_("add the standard git exclusions"),
-                       PARSE_OPT_NOARG, option_parse_exclude_standard },
+                       PARSE_OPT_NOARG | PARSE_OPT_NONEG,
+                       option_parse_exclude_standard },
                OPT_SET_INT_F(0, "full-name", &prefix_len,
                              N_("make the output relative to the project top directory"),
                              0, PARSE_OPT_NONEG),
index b08803e61119a569e2ca5a33402666d8978d9ff0..06a2f90c4875f2a8ff82a927071ac584ad929f8b 100644 (file)
@@ -15,6 +15,8 @@ static int label_cb(const struct option *opt, const char *arg, int unset)
        static int label_count = 0;
        const char **names = (const char **)opt->value;
 
+       BUG_ON_OPT_NEG(unset);
+
        if (label_count >= 3)
                return error("too many labels on the command line");
        names[label_count++] = arg;
index 4aa60715980f2f226d752e9d7fe0df4ecdcc369d..adb0402e847a50bc9e9be69e2257b1b555a780ec 100644 (file)
@@ -224,6 +224,7 @@ static int option_parse_x(const struct option *opt,
 static int option_parse_n(const struct option *opt,
                          const char *arg, int unset)
 {
+       BUG_ON_OPT_ARG(arg);
        show_diffstat = unset;
        return 0;
 }
index c05cd004abcbdcd1e4c3d140f3cf4251c416df36..91faa514aaa7f83b06f8ffc9599164c366c394fb 100644 (file)
@@ -215,6 +215,8 @@ static int parse_msg_arg(const struct option *opt, const char *arg, int unset)
 {
        struct note_data *d = opt->value;
 
+       BUG_ON_OPT_NEG(unset);
+
        strbuf_grow(&d->buf, strlen(arg) + 2);
        if (d->buf.len)
                strbuf_addch(&d->buf, '\n');
@@ -229,6 +231,8 @@ static int parse_file_arg(const struct option *opt, const char *arg, int unset)
 {
        struct note_data *d = opt->value;
 
+       BUG_ON_OPT_NEG(unset);
+
        if (d->buf.len)
                strbuf_addch(&d->buf, '\n');
        if (!strcmp(arg, "-")) {
@@ -250,6 +254,8 @@ static int parse_reuse_arg(const struct option *opt, const char *arg, int unset)
        enum object_type type;
        unsigned long len;
 
+       BUG_ON_OPT_NEG(unset);
+
        if (d->buf.len)
                strbuf_addch(&d->buf, '\n');
 
@@ -273,6 +279,7 @@ static int parse_reuse_arg(const struct option *opt, const char *arg, int unset)
 static int parse_reedit_arg(const struct option *opt, const char *arg, int unset)
 {
        struct note_data *d = opt->value;
+       BUG_ON_OPT_NEG(unset);
        d->use_editor = 1;
        return parse_reuse_arg(opt, arg, unset);
 }
index 2193054d2776b1d0d9f440b6035faacbfd0e4042..794714e4f8703c0efed76fc37006fba05496f660 100644 (file)
@@ -3187,6 +3187,9 @@ static int option_parse_index_version(const struct option *opt,
 {
        char *c;
        const char *val = arg;
+
+       BUG_ON_OPT_NEG(unset);
+
        pack_idx_opts.version = strtoul(val, &c, 10);
        if (pack_idx_opts.version > 2)
                die(_("unsupported index version %s"), val);
@@ -3233,7 +3236,7 @@ int cmd_pack_objects(int argc, const char **argv, const char *prefix)
                         N_("similar to --all-progress when progress meter is shown")),
                { OPTION_CALLBACK, 0, "index-version", NULL, N_("<version>[,<offset>]"),
                  N_("write the pack index file in the specified idx format version"),
-                 0, option_parse_index_version },
+                 PARSE_OPT_NONEG, option_parse_index_version },
                OPT_MAGNITUDE(0, "max-pack-size", &pack_size_limit,
                              N_("maximum size of each output pack file")),
                OPT_BOOL(0, "local", &local,
index fbbc98e5161f011a25743a528e6bb3f85e415f51..183ee8c1e5d4de53d10e9ed00c624f615baf3fc9 100644 (file)
@@ -44,6 +44,7 @@ static const char * const read_tree_usage[] = {
 static int index_output_cb(const struct option *opt, const char *arg,
                                 int unset)
 {
+       BUG_ON_OPT_NEG(unset);
        set_alternate_index_output(arg);
        return 0;
 }
@@ -54,6 +55,8 @@ static int exclude_per_directory_cb(const struct option *opt, const char *arg,
        struct dir_struct *dir;
        struct unpack_trees_options *opts;
 
+       BUG_ON_OPT_NEG(unset);
+
        opts = (struct unpack_trees_options *)opt->value;
 
        if (opts->dir)
index 0ee06aa3631ee89761d570b433994cc77302742e..b84568fc4e6677e5f68c3b11e0798942ae19577a 100644 (file)
@@ -703,6 +703,9 @@ static int parse_opt_merge(const struct option *opt, const char *arg, int unset)
 {
        struct rebase_options *opts = opt->value;
 
+       BUG_ON_OPT_NEG(unset);
+       BUG_ON_OPT_ARG(arg);
+
        if (!is_interactive(opts))
                opts->type = REBASE_MERGE;
 
@@ -715,6 +718,9 @@ static int parse_opt_interactive(const struct option *opt, const char *arg,
 {
        struct rebase_options *opts = opt->value;
 
+       BUG_ON_OPT_NEG(unset);
+       BUG_ON_OPT_ARG(arg);
+
        opts->type = REBASE_INTERACTIVE;
        opts->flags |= REBASE_INTERACTIVE_EXPLICIT;
 
index 65f4a4c83c42ec33d5ffe3f1d83d7b5465c0796d..934e5149448783e32acc8b605f202384af7d96ee 100644 (file)
@@ -604,6 +604,7 @@ static int parse_reflog_param(const struct option *opt, const char *arg,
 {
        char *ep;
        const char **base = (const char **)opt->value;
+       BUG_ON_OPT_NEG(unset);
        if (!arg)
                arg = "";
        reflog = strtoul(arg, &ep, 10);
@@ -674,7 +675,7 @@ int cmd_show_branch(int ac, const char **av, const char *prefix)
                { OPTION_CALLBACK, 'g', "reflog", &reflog_base, N_("<n>[,<base>]"),
                            N_("show <n> most recent ref-log entries starting at "
                               "base"),
-                           PARSE_OPT_OPTARG,
+                           PARSE_OPT_OPTARG | PARSE_OPT_NONEG,
                            parse_reflog_param },
                OPT_END()
        };
index 2f13f1316fadc2fc860fac75a161b47f7d11e391..ed888ffa48ce1d5ef80859b8f5b3bf1720e49abd 100644 (file)
@@ -151,6 +151,7 @@ static int hash_callback(const struct option *opt, const char *arg, int unset)
 static int exclude_existing_callback(const struct option *opt, const char *arg,
                                     int unset)
 {
+       BUG_ON_OPT_NEG(unset);
        exclude_arg = 1;
        *(const char **)opt->value = arg;
        return 0;
index f6236321865773cb60907bfe8b56d96bbaf3e83a..02f6bd1279d9c360f97d04ebba0b1f88ff2f27e1 100644 (file)
@@ -338,6 +338,8 @@ static int parse_msg_arg(const struct option *opt, const char *arg, int unset)
 {
        struct msg_arg *msg = opt->value;
 
+       BUG_ON_OPT_NEG(unset);
+
        if (!arg)
                return -1;
        if (msg->buf.len)
@@ -390,8 +392,8 @@ int cmd_tag(int argc, const char **argv, const char *prefix)
                OPT_GROUP(N_("Tag creation options")),
                OPT_BOOL('a', "annotate", &annotate,
                                        N_("annotated tag, needs a message")),
-               OPT_CALLBACK('m', "message", &msg, N_("message"),
-                            N_("tag message"), parse_msg_arg),
+               { OPTION_CALLBACK, 'm', "message", &msg, N_("message"),
+                 N_("tag message"), PARSE_OPT_NONEG, parse_msg_arg },
                OPT_FILENAME('F', "file", &msgfile, N_("read message from file")),
                OPT_BOOL('e', "edit", &edit_flag, N_("force edit of tag message")),
                OPT_BOOL('s', "sign", &opt.sign, N_("annotated and GPG-signed tag")),
index 0e1dcf0438f7b2ec37b404d3f2acb7bd70650b67..31e7cce3013a3b3f358834f24848fc73b67f8e8b 100644 (file)
@@ -790,12 +790,16 @@ static int refresh(struct refresh_params *o, unsigned int flag)
 static int refresh_callback(const struct option *opt,
                                const char *arg, int unset)
 {
+       BUG_ON_OPT_NEG(unset);
+       BUG_ON_OPT_ARG(arg);
        return refresh(opt->value, 0);
 }
 
 static int really_refresh_callback(const struct option *opt,
                                const char *arg, int unset)
 {
+       BUG_ON_OPT_NEG(unset);
+       BUG_ON_OPT_ARG(arg);
        return refresh(opt->value, REFRESH_REALLY);
 }
 
@@ -803,6 +807,7 @@ static int chmod_callback(const struct option *opt,
                                const char *arg, int unset)
 {
        char *flip = opt->value;
+       BUG_ON_OPT_NEG(unset);
        if ((arg[0] != '-' && arg[0] != '+') || arg[1] != 'x' || arg[2])
                return error("option 'chmod' expects \"+x\" or \"-x\"");
        *flip = arg[0];
@@ -812,6 +817,8 @@ static int chmod_callback(const struct option *opt,
 static int resolve_undo_clear_callback(const struct option *opt,
                                const char *arg, int unset)
 {
+       BUG_ON_OPT_NEG(unset);
+       BUG_ON_OPT_ARG(arg);
        resolve_undo_clear();
        return 0;
 }
@@ -847,6 +854,8 @@ static int cacheinfo_callback(struct parse_opt_ctx_t *ctx,
        unsigned int mode;
        const char *path;
 
+       BUG_ON_OPT_NEG(unset);
+
        if (!parse_new_style_cacheinfo(ctx->argv[1], &mode, &oid, &path)) {
                if (add_cacheinfo(mode, &oid, path, 0))
                        die("git update-index: --cacheinfo cannot add %s", path);
@@ -869,6 +878,8 @@ static int stdin_cacheinfo_callback(struct parse_opt_ctx_t *ctx,
 {
        int *nul_term_line = opt->value;
 
+       BUG_ON_OPT_NEG(unset);
+
        if (ctx->argc != 1)
                return error("option '%s' must be the last argument", opt->long_name);
        allow_add = allow_replace = allow_remove = 1;
@@ -881,6 +892,8 @@ static int stdin_callback(struct parse_opt_ctx_t *ctx,
 {
        int *read_from_stdin = opt->value;
 
+       BUG_ON_OPT_NEG(unset);
+
        if (ctx->argc != 1)
                return error("option '%s' must be the last argument", opt->long_name);
        *read_from_stdin = 1;
@@ -888,11 +901,13 @@ static int stdin_callback(struct parse_opt_ctx_t *ctx,
 }
 
 static int unresolve_callback(struct parse_opt_ctx_t *ctx,
-                               const struct option *opt, int flags)
+                               const struct option *opt, int unset)
 {
        int *has_errors = opt->value;
        const char *prefix = startup_info->prefix;
 
+       BUG_ON_OPT_NEG(unset);
+
        /* consume remaining arguments. */
        *has_errors = do_unresolve(ctx->argc, ctx->argv,
                                prefix, prefix ? strlen(prefix) : 0);
@@ -905,11 +920,13 @@ static int unresolve_callback(struct parse_opt_ctx_t *ctx,
 }
 
 static int reupdate_callback(struct parse_opt_ctx_t *ctx,
-                               const struct option *opt, int flags)
+                               const struct option *opt, int unset)
 {
        int *has_errors = opt->value;
        const char *prefix = startup_info->prefix;
 
+       BUG_ON_OPT_NEG(unset);
+
        /* consume remaining arguments. */
        setup_work_tree();
        *has_errors = do_reupdate(ctx->argc, ctx->argv,
diff --git a/midx.c b/midx.c
index a50b117b777d2659a6d930997ced4f43fbbc3e46..730ff84dff6cb23e4ba2218e956629dc1465744b 100644 (file)
--- a/midx.c
+++ b/midx.c
@@ -721,12 +721,18 @@ static size_t write_midx_object_offsets(struct hashfile *f, int large_offset_nee
 static size_t write_midx_large_offsets(struct hashfile *f, uint32_t nr_large_offset,
                                       struct pack_midx_entry *objects, uint32_t nr_objects)
 {
-       struct pack_midx_entry *list = objects;
+       struct pack_midx_entry *list = objects, *end = objects + nr_objects;
        size_t written = 0;
 
        while (nr_large_offset) {
-               struct pack_midx_entry *obj = list++;
-               uint64_t offset = obj->offset;
+               struct pack_midx_entry *obj;
+               uint64_t offset;
+
+               if (list >= end)
+                       BUG("too many large-offset objects");
+
+               obj = list++;
+               offset = obj->offset;
 
                if (!(offset >> 31))
                        continue;
index e8236534ac8aa00fde2a5a9ae27e85c72d062f3a..8c9edce52f63bcb1085b119b3a2264a97b1fb374 100644 (file)
@@ -28,13 +28,6 @@ int parse_opt_abbrev_cb(const struct option *opt, const char *arg, int unset)
        return 0;
 }
 
-int parse_opt_approxidate_cb(const struct option *opt, const char *arg,
-                            int unset)
-{
-       *(timestamp_t *)(opt->value) = approxidate(arg);
-       return 0;
-}
-
 int parse_opt_expiry_date_cb(const struct option *opt, const char *arg,
                             int unset)
 {
@@ -65,6 +58,8 @@ int parse_opt_verbosity_cb(const struct option *opt, const char *arg,
 {
        int *target = opt->value;
 
+       BUG_ON_OPT_ARG(arg);
+
        if (unset)
                /* --no-quiet, --no-verbose */
                *target = 0;
@@ -87,6 +82,8 @@ int parse_opt_commits(const struct option *opt, const char *arg, int unset)
        struct object_id oid;
        struct commit *commit;
 
+       BUG_ON_OPT_NEG(unset);
+
        if (!arg)
                return -1;
        if (get_oid(arg, &oid))
@@ -117,6 +114,9 @@ int parse_opt_object_name(const struct option *opt, const char *arg, int unset)
 int parse_opt_tertiary(const struct option *opt, const char *arg, int unset)
 {
        int *target = opt->value;
+
+       BUG_ON_OPT_ARG(arg);
+
        *target = unset ? 2 : 1;
        return 0;
 }
index dd14911a297a5b10705ecb31243c55a7dc2f193c..6c4fe2016d65f1093400f8f5080085eb244f0026 100644 (file)
@@ -150,9 +150,6 @@ struct option {
                                      (h), 0, &parse_opt_string_list }
 #define OPT_UYN(s, l, v, h)         { OPTION_CALLBACK, (s), (l), (v), NULL, \
                                      (h), PARSE_OPT_NOARG, &parse_opt_tertiary }
-#define OPT_DATE(s, l, v, h) \
-       { OPTION_CALLBACK, (s), (l), (v), N_("time"),(h), 0,    \
-         parse_opt_approxidate_cb }
 #define OPT_EXPIRY_DATE(s, l, v, h) \
        { OPTION_CALLBACK, (s), (l), (v), N_("expiry-date"),(h), 0,     \
          parse_opt_expiry_date_cb }
@@ -194,6 +191,20 @@ extern int opterror(const struct option *opt, const char *reason, int flags);
 #define opterror(o,r,f) (opterror((o),(r),(f)), const_error())
 #endif
 
+/*
+ * Use these assertions for callbacks that expect to be called with NONEG and
+ * NOARG respectively, and do not otherwise handle the "unset" and "arg"
+ * parameters.
+ */
+#define BUG_ON_OPT_NEG(unset) do { \
+       if ((unset)) \
+               BUG("option callback does not expect negation"); \
+} while (0)
+#define BUG_ON_OPT_ARG(arg) do { \
+       if ((arg)) \
+               BUG("option callback does not expect an argument"); \
+} while (0)
+
 /*----- incremental advanced APIs -----*/
 
 enum {
@@ -232,7 +243,6 @@ extern struct option *parse_options_concat(struct option *a, struct option *b);
 
 /*----- some often used options -----*/
 extern int parse_opt_abbrev_cb(const struct option *, const char *, int);
-extern int parse_opt_approxidate_cb(const struct option *, const char *, int);
 extern int parse_opt_expiry_date_cb(const struct option *, const char *, int);
 extern int parse_opt_color_flag_cb(const struct option *, const char *, int);
 extern int parse_opt_verbosity_cb(const struct option *, const char *, int);
index 0c45ed9d94a4bd4bfab6c9d441ca9bc7de7ebf31..7eca4362236cb6aee15999ee290a08c4ee06278d 100644 (file)
@@ -2316,6 +2316,8 @@ int parse_opt_merge_filter(const struct option *opt, const char *arg, int unset)
        struct object_id oid;
        int no_merged = starts_with(opt->long_name, "no");
 
+       BUG_ON_OPT_NEG(unset);
+
        if (rf->merge) {
                if (no_merged) {
                        return opterror(opt, "is incompatible with --merged", 0);
index 9cb8a0ea0f8ae7b3da8525b2a354bfa542db93c3..47fee660b86a6e6977735e2c940de79d4330d519 100644 (file)
@@ -36,6 +36,7 @@ static int length_callback(const struct option *opt, const char *arg, int unset)
 
 static int number_callback(const struct option *opt, const char *arg, int unset)
 {
+       BUG_ON_OPT_NEG(unset);
        *(int *)opt->value = strtol(arg, NULL, 10);
        return 0;
 }
@@ -119,7 +120,6 @@ int cmd__parse_options(int argc, const char **argv)
                OPT_INTEGER('j', NULL, &integer, "get a integer, too"),
                OPT_MAGNITUDE('m', "magnitude", &magnitude, "get a magnitude"),
                OPT_SET_INT(0, "set23", &integer, "set integer to 23", 23),
-               OPT_DATE('t', NULL, &timestamp, "get timestamp of <time>"),
                OPT_CALLBACK('L', "length", &integer, "str",
                        "get length of <str>", length_callback),
                OPT_FILENAME('F', "file", &file, "set file to <file>"),
index 17d0c18feb84e2c47167b9b54f71f192d78b0e9b..f5b10861c498e435155f6aec5dec6f27c82aa51b 100755 (executable)
@@ -23,7 +23,6 @@ usage: test-tool parse-options <options>
     -j <n>                get a integer, too
     -m, --magnitude <n>   get a magnitude
     --set23               set integer to 23
-    -t <time>             get timestamp of <time>
     -L, --length <str>    get length of <str>
     -F, --file <file>     set file to <file>
 
@@ -245,27 +244,6 @@ test_expect_success 'keep some options as arguments' '
        test-tool parse-options --expect="arg 00: --quux" --quux
 '
 
-cat >expect <<\EOF
-boolean: 0
-integer: 0
-magnitude: 0
-timestamp: 1
-string: (not set)
-abbrev: 7
-verbose: -1
-quiet: 1
-dry run: no
-file: (not set)
-arg 00: foo
-EOF
-
-test_expect_success 'OPT_DATE() works' '
-       test-tool parse-options -t "1970-01-01 00:00:01 +0000" \
-               foo -q >output 2>output.err &&
-       test_must_be_empty output.err &&
-       test_cmp expect output
-'
-
 cat >expect <<\EOF
 Callback: "four", 0
 boolean: 5