git-blame: migrate to incremental parse-option [1/2]
This step merely moves the parser to an incremental version, still using parse_revisions. Signed-off-by: Pierre Habouzit <madcoder@debian.org> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Pierre Habouzit committed
Jul 8, 2008 at 15:19 UTC
5817da01434a24e693ea4d5ba6680d488f5f543f
1 file changed
+118
-102
builtin-blame.c
+118
-102
@@ -18,24 +18,16 @@
18
#include "cache-tree.h"
19
#include "path-list.h"
20
#include "mailmap.h"
21
+#include "parse-options.h"
22
22
-static char blame_usage[] =
23
-"git-blame [-c] [-b] [-l] [--root] [-t] [-f] [-n] [-s] [-p] [-w] [-L n,m] [-S <revs-file>] [-M] [-C] [-C] [--contents <filename>] [--incremental] [commit] [--] file\n"
24
-" -c Use the same output mode as git-annotate (Default: off)\n"
25
-" -b Show blank SHA-1 for boundary commits (Default: off)\n"
26
-" -l Show long commit SHA1 (Default: off)\n"
27
-" --root Do not treat root commits as boundaries (Default: off)\n"
28
-" -t Show raw timestamp (Default: off)\n"
29
-" -f, --show-name Show original filename (Default: auto)\n"
30
-" -n, --show-number Show original linenumber (Default: off)\n"
31
-" -s Suppress author name and timestamp (Default: off)\n"
32
-" -p, --porcelain Show in a format designed for machine consumption\n"
33
-" -w Ignore whitespace differences\n"
34
-" -L n,m Process only line range n,m, counting from 1\n"
35
-" -M, -C Find line movements within and across files\n"
36
-" --incremental Show blame entries as we find them, incrementally\n"
37
-" --contents file Use <file>'s contents as the final image\n"
38
-" -S revs-file Use revisions from revs-file instead of calling git-rev-list\n";
23
+static char blame_usage[] = "git-blame [options] [rev-opts] [rev] [--] file";
24
+
25
+static const char *blame_opt_usage[] = {
26
+ blame_usage,
27
+ "",
28
+ "[rev-opts] are documented in git-rev-parse(1)",
29
+ NULL
30
+};
31
32
static int longest_file;
33
static int longest_author;
@@ -2219,6 +2211,50 @@ static const char *prepare_initial(struct scoreboard *sb)
2211
return final_commit_name;
2212
}
2213
2214
+static int blame_copy_callback(const struct option *option, const char *arg, int unset)
2215
+{
2216
+ int *opt = option->value;
2217
+
2218
+ /*
2219
+ * -C enables copy from removed files;
2220
+ * -C -C enables copy from existing files, but only
2221
+ * when blaming a new file;
2222
+ * -C -C -C enables copy from existing files for
2223
+ * everybody
2224
+ */
2225
+ if (*opt & PICKAXE_BLAME_COPY_HARDER)
2226
+ *opt |= PICKAXE_BLAME_COPY_HARDEST;
2227
+ if (*opt & PICKAXE_BLAME_COPY)
2228
+ *opt |= PICKAXE_BLAME_COPY_HARDER;
2229
+ *opt |= PICKAXE_BLAME_COPY | PICKAXE_BLAME_MOVE;
2230
+
2231
+ if (arg)
2232
+ blame_copy_score = parse_score(arg);
2233
+ return 0;
2234
+}
2235
+
2236
+static int blame_move_callback(const struct option *option, const char *arg, int unset)
2237
+{
2238
+ int *opt = option->value;
2239
+
2240
+ *opt |= PICKAXE_BLAME_MOVE;
2241
+
2242
+ if (arg)
2243
+ blame_move_score = parse_score(arg);
2244
+ return 0;
2245
+}
2246
+
2247
+static int blame_bottomtop_callback(const struct option *option, const char *arg, int unset)
2248
+{
2249
+ const char **bottomtop = option->value;
2250
+ if (!arg)
2251
+ return -1;
2252
+ if (*bottomtop)
2253
+ die("More than one '-L n,m' option given");
2254
+ *bottomtop = arg;
2255
+ return 0;
2256
+}
2257
+
2258
int cmd_blame(int argc, const char **argv, const char *prefix)
2259
{
2260
struct rev_info revs;
@@ -2226,98 +2262,79 @@ int cmd_blame(int argc, const char **argv, const char *prefix)
2262
struct scoreboard sb;
2263
struct origin *o;
2264
struct blame_entry *ent;
2229
- int i, seen_dashdash, unk, opt;
2265
+ int i, seen_dashdash, unk;
2266
long bottom, top, lno;
2231
- int output_option = 0;
2232
- int show_stats = 0;
2233
- const char *revs_file = NULL;
2267
const char *final_commit_name = NULL;
2268
enum object_type type;
2236
- const char *bottomtop = NULL;
2237
- const char *contents_from = NULL;
2269
+
2270
+ static const char *bottomtop = NULL;
2271
+ static int output_option = 0, opt = 0;
2272
+ static int show_stats = 0;
2273
+ static const char *revs_file = NULL;
2274
+ static const char *contents_from = NULL;
2275
+ static const struct option options[] = {
2276
+ OPT_BOOLEAN(0, "incremental", &incremental, "Show blame entries as we find them, incrementally"),
2277
+ OPT_BOOLEAN('b', NULL, &blank_boundary, "Show blank SHA-1 for boundary commits (Default: off)"),
2278
+ OPT_BOOLEAN(0, "root", &show_root, "Do not treat root commits as boundaries (Default: off)"),
2279
+ OPT_BOOLEAN(0, "show-stats", &show_stats, "Show work cost statistics"),
2280
+ OPT_BIT(0, "score-debug", &output_option, "Show output score for blame entries", OUTPUT_SHOW_SCORE),
2281
+ OPT_BIT('f', "show-name", &output_option, "Show original filename (Default: auto)", OUTPUT_SHOW_NAME),
2282
+ OPT_BIT('n', "show-number", &output_option, "Show original linenumber (Default: off)", OUTPUT_SHOW_NUMBER),
2283
+ OPT_BIT('p', "porcelain", &output_option, "Show in a format designed for machine consumption", OUTPUT_PORCELAIN),
2284
+ OPT_BIT('c', NULL, &output_option, "Use the same output mode as git-annotate (Default: off)", OUTPUT_ANNOTATE_COMPAT),
2285
+ OPT_BIT('t', NULL, &output_option, "Show raw timestamp (Default: off)", OUTPUT_RAW_TIMESTAMP),
2286
+ OPT_BIT('l', NULL, &output_option, "Show long commit SHA1 (Default: off)", OUTPUT_LONG_OBJECT_NAME),
2287
+ OPT_BIT('s', NULL, &output_option, "Suppress author name and timestamp (Default: off)", OUTPUT_NO_AUTHOR),
2288
+ OPT_BIT('w', NULL, &xdl_opts, "Ignore whitespace differences", XDF_IGNORE_WHITESPACE),
2289
+ OPT_STRING('S', NULL, &revs_file, "file", "Use revisions from <file> instead of calling git-rev-list"),
2290
+ OPT_STRING(0, "contents", &contents_from, "file", "Use <file>'s contents as the final image"),
2291
+ { OPTION_CALLBACK, 'C', NULL, &opt, "score", "Find line copies within and across files", PARSE_OPT_OPTARG, blame_copy_callback },
2292
+ { OPTION_CALLBACK, 'M', NULL, &opt, "score", "Find line movements within and across files", PARSE_OPT_OPTARG, blame_move_callback },
2293
+ OPT_CALLBACK('L', NULL, &bottomtop, "n,m", "Process only line range n,m, counting from 1", blame_bottomtop_callback),
2294
+ OPT_END()
2295
+ };
2296
+
2297
+ struct parse_opt_ctx_t ctx;
2298
2299
cmd_is_annotate = !strcmp(argv[0], "annotate");
2300
2301
git_config(git_blame_config, NULL);
2302
+ init_revisions(&revs, NULL);
2303
save_commit_buffer = 0;
2304
2244
- opt = 0;
2305
+ parse_options_start(&ctx, argc, argv, PARSE_OPT_KEEP_DASHDASH |
2306
+ PARSE_OPT_KEEP_ARGV0);
2307
+ for (;;) {
2308
+ int n;
2309
+
2310
+ switch (parse_options_step(&ctx, options, blame_opt_usage)) {
2311
+ case PARSE_OPT_HELP:
2312
+ exit(129);
2313
+ case PARSE_OPT_DONE:
2314
+ goto parse_done;
2315
+ }
2316
+
2317
+ if (!strcmp(ctx.argv[0], "--reverse")) {
2318
+ ctx.argv[0] = "--children";
2319
+ reverse = 1;
2320
+ }
2321
+ n = handle_revision_opt(&revs, ctx.argc, ctx.argv,
2322
+ &ctx.cpidx, ctx.out);
2323
+ if (n <= 0) {
2324
+ error("unknown option `%s'", ctx.argv[0]);
2325
+ usage_with_options(blame_opt_usage, options);
2326
+ }
2327
+ ctx.argv += n;
2328
+ ctx.argc -= n;
2329
+ }
2330
+parse_done:
2331
+ argc = parse_options_end(&ctx);
2332
+
2333
seen_dashdash = 0;
2334
for (unk = i = 1; i < argc; i++) {
2335
const char *arg = argv[i];
2336
if (*arg != '-')
2337
break;
2250
- else if (!strcmp("-b", arg))
2251
- blank_boundary = 1;
2252
- else if (!strcmp("--root", arg))
2253
- show_root = 1;
2254
- else if (!strcmp("--reverse", arg)) {
2255
- argv[unk++] = "--children";
2256
- reverse = 1;
2257
- }
2258
- else if (!strcmp(arg, "--show-stats"))
2259
- show_stats = 1;
2260
- else if (!strcmp("-c", arg))
2261
- output_option |= OUTPUT_ANNOTATE_COMPAT;
2262
- else if (!strcmp("-t", arg))
2263
- output_option |= OUTPUT_RAW_TIMESTAMP;
2264
- else if (!strcmp("-l", arg))
2265
- output_option |= OUTPUT_LONG_OBJECT_NAME;
2266
- else if (!strcmp("-s", arg))
2267
- output_option |= OUTPUT_NO_AUTHOR;
2268
- else if (!strcmp("-w", arg))
2269
- xdl_opts |= XDF_IGNORE_WHITESPACE;
2270
- else if (!strcmp("-S", arg) && ++i < argc)
2271
- revs_file = argv[i];
2272
- else if (!prefixcmp(arg, "-M")) {
2273
- opt |= PICKAXE_BLAME_MOVE;
2274
- blame_move_score = parse_score(arg+2);
2275
- }
2276
- else if (!prefixcmp(arg, "-C")) {
2277
- /*
2278
- * -C enables copy from removed files;
2279
- * -C -C enables copy from existing files, but only
2280
- * when blaming a new file;
2281
- * -C -C -C enables copy from existing files for
2282
- * everybody
2283
- */
2284
- if (opt & PICKAXE_BLAME_COPY_HARDER)
2285
- opt |= PICKAXE_BLAME_COPY_HARDEST;
2286
- if (opt & PICKAXE_BLAME_COPY)
2287
- opt |= PICKAXE_BLAME_COPY_HARDER;
2288
- opt |= PICKAXE_BLAME_COPY | PICKAXE_BLAME_MOVE;
2289
- blame_copy_score = parse_score(arg+2);
2290
- }
2291
- else if (!prefixcmp(arg, "-L")) {
2292
- if (!arg[2]) {
2293
- if (++i >= argc)
2294
- usage(blame_usage);
2295
- arg = argv[i];
2296
- }
2297
- else
2298
- arg += 2;
2299
- if (bottomtop)
2300
- die("More than one '-L n,m' option given");
2301
- bottomtop = arg;
2302
- }
2303
- else if (!strcmp("--contents", arg)) {
2304
- if (++i >= argc)
2305
- usage(blame_usage);
2306
- contents_from = argv[i];
2307
- }
2308
- else if (!strcmp("--incremental", arg))
2309
- incremental = 1;
2310
- else if (!strcmp("--score-debug", arg))
2311
- output_option |= OUTPUT_SHOW_SCORE;
2312
- else if (!strcmp("-f", arg) ||
2313
- !strcmp("--show-name", arg))
2314
- output_option |= OUTPUT_SHOW_NAME;
2315
- else if (!strcmp("-n", arg) ||
2316
- !strcmp("--show-number", arg))
2317
- output_option |= OUTPUT_SHOW_NUMBER;
2318
- else if (!strcmp("-p", arg) ||
2319
- !strcmp("--porcelain", arg))
2320
- output_option |= OUTPUT_PORCELAIN;
2338
else if (!strcmp("--", arg)) {
2339
seen_dashdash = 1;
2340
i++;
@@ -2364,16 +2381,16 @@ int cmd_blame(int argc, const char **argv, const char *prefix)
2381
if (seen_dashdash) {
2382
/* (1) */
2383
if (argc <= i)
2367
- usage(blame_usage);
2384
+ usage_with_options(blame_opt_usage, options);
2385
path = add_prefix(prefix, argv[i]);
2386
if (i + 1 == argc - 1) {
2387
if (unk != 1)
2371
- usage(blame_usage);
2388
+ usage_with_options(blame_opt_usage, options);
2389
argv[unk++] = argv[i + 1];
2390
}
2391
else if (i + 1 != argc)
2392
/* garbage at end */
2376
- usage(blame_usage);
2393
+ usage_with_options(blame_opt_usage, options);
2394
}
2395
else {
2396
int j;
@@ -2383,7 +2400,7 @@ int cmd_blame(int argc, const char **argv, const char *prefix)
2400
if (seen_dashdash) {
2401
/* (2) */
2402
if (seen_dashdash + 1 != argc - 1)
2386
- usage(blame_usage);
2403
+ usage_with_options(blame_opt_usage, options);
2404
path = add_prefix(prefix, argv[seen_dashdash + 1]);
2405
for (j = i; j < seen_dashdash; j++)
2406
argv[unk++] = argv[j];
@@ -2391,7 +2408,7 @@ int cmd_blame(int argc, const char **argv, const char *prefix)
2408
else {
2409
/* (3) */
2410
if (argc <= i)
2394
- usage(blame_usage);
2411
+ usage_with_options(blame_opt_usage, options);
2412
path = add_prefix(prefix, argv[i]);
2413
if (i + 1 == argc - 1) {
2414
final_commit_name = argv[i + 1];
@@ -2405,7 +2422,7 @@ int cmd_blame(int argc, const char **argv, const char *prefix)
2422
}
2423
}
2424
else if (i != argc - 1)
2408
- usage(blame_usage); /* garbage at end */
2425
+ usage_with_options(blame_opt_usage, options);
2426
2427
setup_work_tree();
2428
if (!has_path_in_work_tree(path))
@@ -2424,7 +2441,6 @@ int cmd_blame(int argc, const char **argv, const char *prefix)
2441
argv[unk++] = "--"; /* terminate the rev name */
2442
argv[unk] = NULL;
2443
2427
- init_revisions(&revs, NULL);
2444
setup_revisions(unk, argv, &revs, NULL);
2445
memset(&sb, 0, sizeof(sb));
2446