git-blame: migrate to incremental parse-option [2/2]
authorPierre Habouzit <madcoder@debian.org>
Tue, 8 Jul 2008 13:19:35 +0000 (15:19 +0200)
committerJunio C Hamano <gitster@pobox.com>
Tue, 8 Jul 2008 22:54:01 +0000 (15:54 -0700)
Now use handle_revision_args instead of parse_revisions, and simplify the
handling of old-style arguments a lot thanks to the filtering.

Signed-off-by: Pierre Habouzit <madcoder@debian.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
builtin-blame.c

index 5e82cd3d54c4013e29e3b502f01ce1e5af968507..99f5140013d9c4c0502ca814371c4757751fd1ac 100644 (file)
@@ -2262,8 +2262,7 @@ int cmd_blame(int argc, const char **argv, const char *prefix)
        struct scoreboard sb;
        struct origin *o;
        struct blame_entry *ent;
-       int i, seen_dashdash, unk;
-       long bottom, top, lno;
+       long dashdash_pos, bottom, top, lno;
        const char *final_commit_name = NULL;
        enum object_type type;
 
@@ -2301,6 +2300,7 @@ int cmd_blame(int argc, const char **argv, const char *prefix)
        git_config(git_blame_config, NULL);
        init_revisions(&revs, NULL);
        save_commit_buffer = 0;
+       dashdash_pos = 0;
 
        parse_options_start(&ctx, argc, argv, PARSE_OPT_KEEP_DASHDASH |
                            PARSE_OPT_KEEP_ARGV0);
@@ -2311,6 +2311,8 @@ int cmd_blame(int argc, const char **argv, const char *prefix)
                case PARSE_OPT_HELP:
                        exit(129);
                case PARSE_OPT_DONE:
+                       if (ctx.argv[0])
+                               dashdash_pos = ctx.cpidx;
                        goto parse_done;
                }
 
@@ -2330,20 +2332,6 @@ int cmd_blame(int argc, const char **argv, const char *prefix)
 parse_done:
        argc = parse_options_end(&ctx);
 
-       seen_dashdash = 0;
-       for (unk = i = 1; i < argc; i++) {
-               const char *arg = argv[i];
-               if (*arg != '-')
-                       break;
-               else if (!strcmp("--", arg)) {
-                       seen_dashdash = 1;
-                       i++;
-                       break;
-               }
-               else
-                       argv[unk++] = arg;
-       }
-
        if (!blame_move_score)
                blame_move_score = BLAME_DEFAULT_MOVE_SCORE;
        if (!blame_copy_score)
@@ -2356,92 +2344,50 @@ parse_done:
         *
         * The remaining are:
         *
-        * (1) if seen_dashdash, its either
-        *     "-options -- <path>" or
-        *     "-options -- <path> <rev>".
-        *     but the latter is allowed only if there is no
-        *     options that we passed to revision machinery.
+        * (1) if dashdash_pos != 0, its either
+        *     "blame [revisions] -- <path>" or
+        *     "blame -- <path> <rev>"
         *
-        * (2) otherwise, we may have "--" somewhere later and
-        *     might be looking at the first one of multiple 'rev'
-        *     parameters (e.g. " master ^next ^maint -- path").
-        *     See if there is a dashdash first, and give the
-        *     arguments before that to revision machinery.
-        *     After that there must be one 'path'.
+        * (2) otherwise, its one of the two:
+        *     "blame [revisions] <path>"
+        *     "blame <path> <rev>"
         *
-        * (3) otherwise, its one of the three:
-        *     "-options <path> <rev>"
-        *     "-options <rev> <path>"
-        *     "-options <path>"
-        *     but again the first one is allowed only if
-        *     there is no options that we passed to revision
-        *     machinery.
+        * Note that we must strip out <path> from the arguments: we do not
+        * want the path pruning but we may want "bottom" processing.
         */
-
-       if (seen_dashdash) {
-               /* (1) */
-               if (argc <= i)
-                       usage_with_options(blame_opt_usage, options);
-               path = add_prefix(prefix, argv[i]);
-               if (i + 1 == argc - 1) {
-                       if (unk != 1)
+       if (dashdash_pos) {
+               switch (argc - dashdash_pos - 1) {
+               case 2: /* (1b) */
+                       if (argc != 4)
                                usage_with_options(blame_opt_usage, options);
-                       argv[unk++] = argv[i + 1];
+                       /* reorder for the new way: <rev> -- <path> */
+                       argv[1] = argv[3];
+                       argv[3] = argv[2];
+                       argv[2] = "--";
+                       /* FALLTHROUGH */
+               case 1: /* (1a) */
+                       path = add_prefix(prefix, argv[--argc]);
+                       argv[argc] = NULL;
+                       break;
+               default:
+                       usage_with_options(blame_opt_usage, options);
                }
-               else if (i + 1 != argc)
-                       /* garbage at end */
+       } else {
+               if (argc < 2)
                        usage_with_options(blame_opt_usage, options);
-       }
-       else {
-               int j;
-               for (j = i; !seen_dashdash && j < argc; j++)
-                       if (!strcmp(argv[j], "--"))
-                               seen_dashdash = j;
-               if (seen_dashdash) {
-                       /* (2) */
-                       if (seen_dashdash + 1 != argc - 1)
-                               usage_with_options(blame_opt_usage, options);
-                       path = add_prefix(prefix, argv[seen_dashdash + 1]);
-                       for (j = i; j < seen_dashdash; j++)
-                               argv[unk++] = argv[j];
+               path = add_prefix(prefix, argv[argc - 1]);
+               if (argc == 3 && !has_path_in_work_tree(path)) { /* (2b) */
+                       path = add_prefix(prefix, argv[1]);
+                       argv[1] = argv[2];
                }
-               else {
-                       /* (3) */
-                       if (argc <= i)
-                               usage_with_options(blame_opt_usage, options);
-                       path = add_prefix(prefix, argv[i]);
-                       if (i + 1 == argc - 1) {
-                               final_commit_name = argv[i + 1];
-
-                               /* if (unk == 1) we could be getting
-                                * old-style
-                                */
-                               if (unk == 1 && !has_path_in_work_tree(path)) {
-                                       path = add_prefix(prefix, argv[i + 1]);
-                                       final_commit_name = argv[i];
-                               }
-                       }
-                       else if (i != argc - 1)
-                               usage_with_options(blame_opt_usage, options);
+               argv[argc - 1] = "--";
 
-                       setup_work_tree();
-                       if (!has_path_in_work_tree(path))
-                               die("cannot stat path %s: %s",
-                                   path, strerror(errno));
-               }
+               setup_work_tree();
+               if (!has_path_in_work_tree(path))
+                       die("cannot stat path %s: %s", path, strerror(errno));
        }
 
-       if (final_commit_name)
-               argv[unk++] = final_commit_name;
-
-       /*
-        * Now we got rev and path.  We do not want the path pruning
-        * but we may want "bottom" processing.
-        */
-       argv[unk++] = "--"; /* terminate the rev name */
-       argv[unk] = NULL;
-
-       setup_revisions(unk, argv, &revs, NULL);
+       setup_revisions(argc, argv, &revs, NULL);
        memset(&sb, 0, sizeof(sb));
 
        sb.revs = &revs;