git-shortlog: migrate to parse-options partially.
Signed-off-by: Pierre Habouzit <madcoder@debian.org> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Pierre Habouzit committed
Jul 9, 2008 at 23:38 UTC
14ec9cbdae1991a14aa1cce251e44ea5cfee5ade
1 file changed
+77
-58
builtin-shortlog.c
+77
-58
@@ -7,9 +7,14 @@
7
#include "utf8.h"
8
#include "mailmap.h"
9
#include "shortlog.h"
10
+#include "parse-options.h"
11
11
-static const char shortlog_usage[] =
12
-"git-shortlog [-n] [-s] [-e] [-w] [<commit-id>... ]";
12
+static char const * const shortlog_usage[] = {
13
+ "git-shortlog [-n] [-s] [-e] [-w] [rev-opts] [--] [<commit-id>... ]",
14
+ "",
15
+ "[rev-opts] are documented in git-rev-list(1)",
16
+ NULL
17
+};
18
19
static int compare_by_number(const void *a1, const void *a2)
20
{
@@ -164,21 +169,19 @@ static void get_from_rev(struct rev_info *rev, struct shortlog *log)
169
shortlog_add_commit(log, commit);
170
}
171
167
-static int parse_uint(char const **arg, int comma)
172
+static int parse_uint(char const **arg, int comma, int defval)
173
{
174
unsigned long ul;
175
int ret;
176
char *endp;
177
178
ul = strtoul(*arg, &endp, 10);
174
- if (endp != *arg && *endp && *endp != comma)
179
+ if (*endp && *endp != comma)
180
return -1;
176
- ret = (int) ul;
177
- if (ret != ul)
181
+ if (ul > INT_MAX)
182
return -1;
179
- *arg = endp;
180
- if (**arg)
181
- (*arg)++;
183
+ ret = *arg == endp ? defval : (int)ul;
184
+ *arg = *endp ? endp + 1 : endp;
185
return ret;
186
}
187
@@ -187,30 +190,30 @@ static const char wrap_arg_usage[] = "-w[<width>[,<indent1>[,<indent2>]]]";
190
#define DEFAULT_INDENT1 6
191
#define DEFAULT_INDENT2 9
192
190
-static void parse_wrap_args(const char *arg, int *in1, int *in2, int *wrap)
193
+static int parse_wrap_args(const struct option *opt, const char *arg, int unset)
194
{
192
- arg += 2; /* skip -w */
193
-
194
- *wrap = parse_uint(&arg, ',');
195
- if (*wrap < 0)
196
- die(wrap_arg_usage);
197
- *in1 = parse_uint(&arg, ',');
198
- if (*in1 < 0)
199
- die(wrap_arg_usage);
200
- *in2 = parse_uint(&arg, '\0');
201
- if (*in2 < 0)
202
- die(wrap_arg_usage);
203
-
204
- if (!*wrap)
205
- *wrap = DEFAULT_WRAPLEN;
206
- if (!*in1)
207
- *in1 = DEFAULT_INDENT1;
208
- if (!*in2)
209
- *in2 = DEFAULT_INDENT2;
210
- if (*wrap &&
211
- ((*in1 && *wrap <= *in1) ||
212
- (*in2 && *wrap <= *in2)))
213
- die(wrap_arg_usage);
195
+ struct shortlog *log = opt->value;
196
+
197
+ log->wrap_lines = !unset;
198
+ if (unset)
199
+ return 0;
200
+ if (!arg) {
201
+ log->wrap = DEFAULT_WRAPLEN;
202
+ log->in1 = DEFAULT_INDENT1;
203
+ log->in2 = DEFAULT_INDENT2;
204
+ return 0;
205
+ }
206
+
207
+ log->wrap = parse_uint(&arg, ',', DEFAULT_WRAPLEN);
208
+ log->in1 = parse_uint(&arg, ',', DEFAULT_INDENT1);
209
+ log->in2 = parse_uint(&arg, '\0', DEFAULT_INDENT2);
210
+ if (log->wrap < 0 || log->in1 < 0 || log->in2 < 0)
211
+ return error(wrap_arg_usage);
212
+ if (log->wrap &&
213
+ ((log->in1 && log->wrap <= log->in1) ||
214
+ (log->in2 && log->wrap <= log->in2)))
215
+ return error(wrap_arg_usage);
216
+ return 0;
217
}
218
219
void shortlog_init(struct shortlog *log)
@@ -227,38 +230,54 @@ void shortlog_init(struct shortlog *log)
230
231
int cmd_shortlog(int argc, const char **argv, const char *prefix)
232
{
230
- struct shortlog log;
231
- struct rev_info rev;
233
+ static struct shortlog log;
234
+ static struct rev_info rev;
235
int nongit;
236
237
+ static const struct option options[] = {
238
+ OPT_BOOLEAN('n', "numbered", &log.sort_by_number,
239
+ "sort output according to the number of commits per author"),
240
+ OPT_BOOLEAN('s', "summary", &log.summary,
241
+ "Suppress commit descriptions, only provides commit count"),
242
+ OPT_BOOLEAN('e', "email", &log.email,
243
+ "Show the email address of each author"),
244
+ { OPTION_CALLBACK, 'w', NULL, &log, "w[,i1[,i2]]",
245
+ "Linewrap output", PARSE_OPT_OPTARG, &parse_wrap_args },
246
+ OPT_END(),
247
+ };
248
+
249
+ struct parse_opt_ctx_t ctx;
250
+
251
prefix = setup_git_directory_gently(&nongit);
252
shortlog_init(&log);
236
-
237
- /* since -n is a shadowed rev argument, parse our args first */
238
- while (argc > 1) {
239
- if (!strcmp(argv[1], "-n") || !strcmp(argv[1], "--numbered"))
240
- log.sort_by_number = 1;
241
- else if (!strcmp(argv[1], "-s") ||
242
- !strcmp(argv[1], "--summary"))
243
- log.summary = 1;
244
- else if (!strcmp(argv[1], "-e") ||
245
- !strcmp(argv[1], "--email"))
246
- log.email = 1;
247
- else if (!prefixcmp(argv[1], "-w")) {
248
- log.wrap_lines = 1;
249
- parse_wrap_args(argv[1], &log.in1, &log.in2, &log.wrap);
253
+ init_revisions(&rev, prefix);
254
+ parse_options_start(&ctx, argc, argv, PARSE_OPT_KEEP_DASHDASH |
255
+ PARSE_OPT_KEEP_ARGV0);
256
+
257
+ for (;;) {
258
+ int n;
259
+ switch (parse_options_step(&ctx, options, shortlog_usage)) {
260
+ case PARSE_OPT_HELP:
261
+ exit(129);
262
+ case PARSE_OPT_DONE:
263
+ goto parse_done;
264
}
251
- else if (!strcmp(argv[1], "-h") || !strcmp(argv[1], "--help"))
252
- usage(shortlog_usage);
253
- else
254
- break;
255
- argv++;
256
- argc--;
265
+ n = handle_revision_opt(&rev, ctx.argc, ctx.argv,
266
+ &ctx.cpidx, ctx.out);
267
+ if (n <= 0) {
268
+ error("unknown option `%s'", ctx.argv[0]);
269
+ usage_with_options(shortlog_usage, options);
270
+ }
271
+ ctx.argv += n;
272
+ ctx.argc -= n;
273
+ }
274
+parse_done:
275
+ argc = parse_options_end(&ctx);
276
+
277
+ if (setup_revisions(argc, argv, &rev, NULL) != 1) {
278
+ error("unrecognized argument: %s", argv[1]);
279
+ usage_with_options(shortlog_usage, options);
280
}
258
- init_revisions(&rev, prefix);
259
- argc = setup_revisions(argc, argv, &rev, NULL);
260
- if (argc > 1)
261
- die ("unrecognized argument: %s", argv[1]);
281
282
/* assume HEAD if from a tty */
283
if (!nongit && !rev.pending.nr && isatty(0))