]> git.ipfire.org Git - thirdparty/git.git/blobdiff - diff.c
use skip_prefix to avoid magic numbers
[thirdparty/git.git] / diff.c
diff --git a/diff.c b/diff.c
index 36679aaf4eab872386a29ee5502fd7282dcbf0a7..97db9323eeb7f6b6522b701da05a42ab92cb1140 100644 (file)
--- a/diff.c
+++ b/diff.c
@@ -52,23 +52,23 @@ static char diff_colors[][COLOR_MAXLEN] = {
        GIT_COLOR_NORMAL,       /* FUNCINFO */
 };
 
-static int parse_diff_color_slot(const char *var, int ofs)
+static int parse_diff_color_slot(const char *var)
 {
-       if (!strcasecmp(var+ofs, "plain"))
+       if (!strcasecmp(var, "plain"))
                return DIFF_PLAIN;
-       if (!strcasecmp(var+ofs, "meta"))
+       if (!strcasecmp(var, "meta"))
                return DIFF_METAINFO;
-       if (!strcasecmp(var+ofs, "frag"))
+       if (!strcasecmp(var, "frag"))
                return DIFF_FRAGINFO;
-       if (!strcasecmp(var+ofs, "old"))
+       if (!strcasecmp(var, "old"))
                return DIFF_FILE_OLD;
-       if (!strcasecmp(var+ofs, "new"))
+       if (!strcasecmp(var, "new"))
                return DIFF_FILE_NEW;
-       if (!strcasecmp(var+ofs, "commit"))
+       if (!strcasecmp(var, "commit"))
                return DIFF_COMMIT;
-       if (!strcasecmp(var+ofs, "whitespace"))
+       if (!strcasecmp(var, "whitespace"))
                return DIFF_WHITESPACE;
-       if (!strcasecmp(var+ofs, "func"))
+       if (!strcasecmp(var, "func"))
                return DIFF_FUNCINFO;
        return -1;
 }
@@ -231,6 +231,8 @@ int git_diff_ui_config(const char *var, const char *value, void *cb)
 
 int git_diff_basic_config(const char *var, const char *value, void *cb)
 {
+       const char *name;
+
        if (!strcmp(var, "diff.renamelimit")) {
                diff_rename_limit_default = git_config_int(var, value);
                return 0;
@@ -239,8 +241,9 @@ int git_diff_basic_config(const char *var, const char *value, void *cb)
        if (userdiff_config(var, value) < 0)
                return -1;
 
-       if (starts_with(var, "diff.color.") || starts_with(var, "color.diff.")) {
-               int slot = parse_diff_color_slot(var, 11);
+       if (skip_prefix(var, "diff.color.", &name) ||
+           skip_prefix(var, "color.diff.", &name)) {
+               int slot = parse_diff_color_slot(name);
                if (slot < 0)
                        return 0;
                if (!value)
@@ -1361,7 +1364,7 @@ static struct diffstat_file *diffstat_add(struct diffstat_t *diffstat,
                                          const char *name_b)
 {
        struct diffstat_file *x;
-       x = xcalloc(sizeof (*x), 1);
+       x = xcalloc(1, sizeof(*x));
        ALLOC_GROW(diffstat->files, diffstat->nr + 1, diffstat->alloc);
        diffstat->files[diffstat->nr++] = x;
        if (name_b) {
@@ -2341,6 +2344,7 @@ static void builtin_diff(const char *name_a,
        } else {
                /* Crazy xdl interfaces.. */
                const char *diffopts = getenv("GIT_DIFF_OPTS");
+               const char *v;
                xpparam_t xpp;
                xdemitconf_t xecfg;
                struct emit_callback ecbdata;
@@ -2379,10 +2383,10 @@ static void builtin_diff(const char *name_a,
                        xdiff_set_find_func(&xecfg, pe->pattern, pe->cflags);
                if (!diffopts)
                        ;
-               else if (starts_with(diffopts, "--unified="))
-                       xecfg.ctxlen = strtoul(diffopts + 10, NULL, 10);
-               else if (starts_with(diffopts, "-u"))
-                       xecfg.ctxlen = strtoul(diffopts + 2, NULL, 10);
+               else if (skip_prefix(diffopts, "--unified=", &v))
+                       xecfg.ctxlen = strtoul(v, NULL, 10);
+               else if (skip_prefix(diffopts, "-u", &v))
+                       xecfg.ctxlen = strtoul(v, NULL, 10);
                if (o->word_diff)
                        init_diff_words_data(&ecbdata, o, one, two);
                xdi_diff_outf(&mf1, &mf2, fn_out_consume, &ecbdata,
@@ -2880,6 +2884,16 @@ static struct diff_tempfile *prepare_temp_file(const char *name,
        return temp;
 }
 
+static void add_external_diff_name(struct argv_array *argv,
+                                  const char *name,
+                                  struct diff_filespec *df)
+{
+       struct diff_tempfile *temp = prepare_temp_file(name, df);
+       argv_array_push(argv, temp->name);
+       argv_array_push(argv, temp->hex);
+       argv_array_push(argv, temp->mode);
+}
+
 /* An external diff command takes:
  *
  * diff-cmd name infile1 infile1-sha1 infile1-mode \
@@ -2896,48 +2910,32 @@ static void run_external_diff(const char *pgm,
                              struct diff_options *o)
 {
        struct argv_array argv = ARGV_ARRAY_INIT;
-       int retval;
+       struct argv_array env = ARGV_ARRAY_INIT;
        struct diff_queue_struct *q = &diff_queued_diff;
-       const char *env[3] = { NULL };
-       char env_counter[50];
-       char env_total[50];
+
+       argv_array_push(&argv, pgm);
+       argv_array_push(&argv, name);
 
        if (one && two) {
-               struct diff_tempfile *temp_one, *temp_two;
-               const char *othername = (other ? other : name);
-               temp_one = prepare_temp_file(name, one);
-               temp_two = prepare_temp_file(othername, two);
-               argv_array_push(&argv, pgm);
-               argv_array_push(&argv, name);
-               argv_array_push(&argv, temp_one->name);
-               argv_array_push(&argv, temp_one->hex);
-               argv_array_push(&argv, temp_one->mode);
-               argv_array_push(&argv, temp_two->name);
-               argv_array_push(&argv, temp_two->hex);
-               argv_array_push(&argv, temp_two->mode);
-               if (other) {
+               add_external_diff_name(&argv, name, one);
+               if (!other)
+                       add_external_diff_name(&argv, name, two);
+               else {
+                       add_external_diff_name(&argv, other, two);
                        argv_array_push(&argv, other);
                        argv_array_push(&argv, xfrm_msg);
                }
-       } else {
-               argv_array_push(&argv, pgm);
-               argv_array_push(&argv, name);
        }
-       fflush(NULL);
 
-       env[0] = env_counter;
-       snprintf(env_counter, sizeof(env_counter), "GIT_DIFF_PATH_COUNTER=%d",
-                ++o->diff_path_counter);
-       env[1] = env_total;
-       snprintf(env_total, sizeof(env_total), "GIT_DIFF_PATH_TOTAL=%d", q->nr);
+       argv_array_pushf(&env, "GIT_DIFF_PATH_COUNTER=%d", ++o->diff_path_counter);
+       argv_array_pushf(&env, "GIT_DIFF_PATH_TOTAL=%d", q->nr);
+
+       if (run_command_v_opt_cd_env(argv.argv, RUN_USING_SHELL, NULL, env.argv))
+               die(_("external diff died, stopping at %s"), name);
 
-       retval = run_command_v_opt_cd_env(argv.argv, RUN_USING_SHELL, NULL, env);
        remove_tempfile();
        argv_array_clear(&argv);
-       if (retval) {
-               fprintf(stderr, "external diff died, stopping at %s.\n", name);
-               exit(1);
-       }
+       argv_array_clear(&env);
 }
 
 static int similarity_index(struct diff_filepair *p)
@@ -3326,6 +3324,9 @@ void diff_setup_done(struct diff_options *options)
        }
 
        options->diff_path_counter = 0;
+
+       if (DIFF_OPT_TST(options, FOLLOW_RENAMES) && options->pathspec.nr != 1)
+               die(_("--follow requires exactly one pathspec"));
 }
 
 static int opt_arg(const char *arg, int arg_short, const char *arg_long, int *val)
@@ -3612,17 +3613,17 @@ int diff_opt_parse(struct diff_options *options, const char **av, int ac)
                options->output_format |= DIFF_FORMAT_SHORTSTAT;
        else if (!strcmp(arg, "-X") || !strcmp(arg, "--dirstat"))
                return parse_dirstat_opt(options, "");
-       else if (starts_with(arg, "-X"))
-               return parse_dirstat_opt(options, arg + 2);
-       else if (starts_with(arg, "--dirstat="))
-               return parse_dirstat_opt(options, arg + 10);
+       else if (skip_prefix(arg, "-X", &arg))
+               return parse_dirstat_opt(options, arg);
+       else if (skip_prefix(arg, "--dirstat=", &arg))
+               return parse_dirstat_opt(options, arg);
        else if (!strcmp(arg, "--cumulative"))
                return parse_dirstat_opt(options, "cumulative");
        else if (!strcmp(arg, "--dirstat-by-file"))
                return parse_dirstat_opt(options, "files");
-       else if (starts_with(arg, "--dirstat-by-file=")) {
+       else if (skip_prefix(arg, "--dirstat-by-file=", &arg)) {
                parse_dirstat_opt(options, "files");
-               return parse_dirstat_opt(options, arg + 18);
+               return parse_dirstat_opt(options, arg);
        }
        else if (!strcmp(arg, "--check"))
                options->output_format |= DIFF_FORMAT_CHECKDIFF;
@@ -3672,9 +3673,9 @@ int diff_opt_parse(struct diff_options *options, const char **av, int ac)
                DIFF_OPT_CLR(options, RENAME_EMPTY);
        else if (!strcmp(arg, "--relative"))
                DIFF_OPT_SET(options, RELATIVE_NAME);
-       else if (starts_with(arg, "--relative=")) {
+       else if (skip_prefix(arg, "--relative=", &arg)) {
                DIFF_OPT_SET(options, RELATIVE_NAME);
-               options->prefix = arg + 11;
+               options->prefix = arg;
        }
 
        /* xdiff options */
@@ -3725,8 +3726,8 @@ int diff_opt_parse(struct diff_options *options, const char **av, int ac)
                DIFF_OPT_CLR(options, FOLLOW_RENAMES);
        else if (!strcmp(arg, "--color"))
                options->use_color = 1;
-       else if (starts_with(arg, "--color=")) {
-               int value = git_config_colorbool(NULL, arg+8);
+       else if (skip_prefix(arg, "--color=", &arg)) {
+               int value = git_config_colorbool(NULL, arg);
                if (value < 0)
                        return error("option `color' expects \"always\", \"auto\", or \"never\"");
                options->use_color = value;
@@ -3737,29 +3738,28 @@ int diff_opt_parse(struct diff_options *options, const char **av, int ac)
                options->use_color = 1;
                options->word_diff = DIFF_WORDS_COLOR;
        }
-       else if (starts_with(arg, "--color-words=")) {
+       else if (skip_prefix(arg, "--color-words=", &arg)) {
                options->use_color = 1;
                options->word_diff = DIFF_WORDS_COLOR;
-               options->word_regex = arg + 14;
+               options->word_regex = arg;
        }
        else if (!strcmp(arg, "--word-diff")) {
                if (options->word_diff == DIFF_WORDS_NONE)
                        options->word_diff = DIFF_WORDS_PLAIN;
        }
-       else if (starts_with(arg, "--word-diff=")) {
-               const char *type = arg + 12;
-               if (!strcmp(type, "plain"))
+       else if (skip_prefix(arg, "--word-diff=", &arg)) {
+               if (!strcmp(arg, "plain"))
                        options->word_diff = DIFF_WORDS_PLAIN;
-               else if (!strcmp(type, "color")) {
+               else if (!strcmp(arg, "color")) {
                        options->use_color = 1;
                        options->word_diff = DIFF_WORDS_COLOR;
                }
-               else if (!strcmp(type, "porcelain"))
+               else if (!strcmp(arg, "porcelain"))
                        options->word_diff = DIFF_WORDS_PORCELAIN;
-               else if (!strcmp(type, "none"))
+               else if (!strcmp(arg, "none"))
                        options->word_diff = DIFF_WORDS_NONE;
                else
-                       die("bad --word-diff argument: %s", type);
+                       die("bad --word-diff argument: %s", arg);
        }
        else if ((argcount = parse_long_opt("word-diff-regex", av, &optarg))) {
                if (options->word_diff == DIFF_WORDS_NONE)
@@ -3782,13 +3782,13 @@ int diff_opt_parse(struct diff_options *options, const char **av, int ac)
        else if (!strcmp(arg, "--ignore-submodules")) {
                DIFF_OPT_SET(options, OVERRIDE_SUBMODULE_CONFIG);
                handle_ignore_submodules_arg(options, "all");
-       } else if (starts_with(arg, "--ignore-submodules=")) {
+       } else if (skip_prefix(arg, "--ignore-submodules=", &arg)) {
                DIFF_OPT_SET(options, OVERRIDE_SUBMODULE_CONFIG);
-               handle_ignore_submodules_arg(options, arg + 20);
+               handle_ignore_submodules_arg(options, arg);
        } else if (!strcmp(arg, "--submodule"))
                DIFF_OPT_SET(options, SUBMODULE_LOG);
-       else if (starts_with(arg, "--submodule="))
-               return parse_submodule_opt(options, arg + 12);
+       else if (skip_prefix(arg, "--submodule=", &arg))
+               return parse_submodule_opt(options, arg);
 
        /* misc options */
        else if (!strcmp(arg, "-z"))
@@ -3823,8 +3823,8 @@ int diff_opt_parse(struct diff_options *options, const char **av, int ac)
        }
        else if (!strcmp(arg, "--abbrev"))
                options->abbrev = DEFAULT_ABBREV;
-       else if (starts_with(arg, "--abbrev=")) {
-               options->abbrev = strtoul(arg + 9, NULL, 10);
+       else if (skip_prefix(arg, "--abbrev=", &arg)) {
+               options->abbrev = strtoul(arg, NULL, 10);
                if (options->abbrev < MINIMUM_ABBREV)
                        options->abbrev = MINIMUM_ABBREV;
                else if (40 < options->abbrev)