Skip to content

Commit 14ec9cb

Browse files
MadCodergitster
authored andcommitted
git-shortlog: migrate to parse-options partially.
Signed-off-by: Pierre Habouzit <madcoder@debian.org> Signed-off-by: Junio C Hamano <gitster@pobox.com>
1 parent 76447d2 commit 14ec9cb

File tree

1 file changed

+77
-58
lines changed

1 file changed

+77
-58
lines changed

builtin-shortlog.c

Lines changed: 77 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,14 @@
77
#include "utf8.h"
88
#include "mailmap.h"
99
#include "shortlog.h"
10+
#include "parse-options.h"
1011

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+
};
1318

1419
static int compare_by_number(const void *a1, const void *a2)
1520
{
@@ -164,21 +169,19 @@ static void get_from_rev(struct rev_info *rev, struct shortlog *log)
164169
shortlog_add_commit(log, commit);
165170
}
166171

167-
static int parse_uint(char const **arg, int comma)
172+
static int parse_uint(char const **arg, int comma, int defval)
168173
{
169174
unsigned long ul;
170175
int ret;
171176
char *endp;
172177

173178
ul = strtoul(*arg, &endp, 10);
174-
if (endp != *arg && *endp && *endp != comma)
179+
if (*endp && *endp != comma)
175180
return -1;
176-
ret = (int) ul;
177-
if (ret != ul)
181+
if (ul > INT_MAX)
178182
return -1;
179-
*arg = endp;
180-
if (**arg)
181-
(*arg)++;
183+
ret = *arg == endp ? defval : (int)ul;
184+
*arg = *endp ? endp + 1 : endp;
182185
return ret;
183186
}
184187

@@ -187,30 +190,30 @@ static const char wrap_arg_usage[] = "-w[<width>[,<indent1>[,<indent2>]]]";
187190
#define DEFAULT_INDENT1 6
188191
#define DEFAULT_INDENT2 9
189192

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)
191194
{
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;
214217
}
215218

216219
void shortlog_init(struct shortlog *log)
@@ -227,38 +230,54 @@ void shortlog_init(struct shortlog *log)
227230

228231
int cmd_shortlog(int argc, const char **argv, const char *prefix)
229232
{
230-
struct shortlog log;
231-
struct rev_info rev;
233+
static struct shortlog log;
234+
static struct rev_info rev;
232235
int nongit;
233236

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+
234251
prefix = setup_git_directory_gently(&nongit);
235252
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;
250264
}
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);
257280
}
258-
init_revisions(&rev, prefix);
259-
argc = setup_revisions(argc, argv, &rev, NULL);
260-
if (argc > 1)
261-
die ("unrecognized argument: %s", argv[1]);
262281

263282
/* assume HEAD if from a tty */
264283
if (!nongit && !rev.pending.nr && isatty(0))

0 commit comments

Comments
 (0)