diff --git a/archive.h b/archive.h index ddf004acdf..1b24ae310d 100644 --- a/archive.h +++ b/archive.h @@ -21,14 +21,11 @@ typedef void *(*parse_extra_args_fn_t)(int argc, const char **argv); struct archiver { const char *name; - struct archiver_args args; write_archive_fn_t write_archive; parse_extra_args_fn_t parse_extra; }; -extern int parse_archive_args(int argc, - const char **argv, - struct archiver *ar); +extern int parse_archive_args(int argc, const char **argv, const struct archiver **ar, struct archiver_args *args); extern void parse_treeish_arg(const char **treeish, struct archiver_args *ar_args, diff --git a/builtin-archive.c b/builtin-archive.c index c2e0c1ea5a..6ee36775e7 100644 --- a/builtin-archive.c +++ b/builtin-archive.c @@ -15,12 +15,7 @@ static const char archive_usage[] = \ "git-archive --format= [--prefix=/] [--verbose] [] [path...]"; -static struct archiver_desc -{ - const char *name; - write_archive_fn_t write_archive; - parse_extra_args_fn_t parse_extra; -} archivers[] = { +const struct archiver archivers[] = { { "tar", write_tar_archive, NULL }, { "zip", write_zip_archive, parse_extra_zip_args }, }; @@ -79,21 +74,15 @@ static int run_remote_archiver(const char *remote, int argc, return !!rv; } -static int init_archiver(const char *name, struct archiver *ar) +static const struct archiver *lookup_archiver(const char *name) { - int rv = -1, i; + int i; for (i = 0; i < ARRAY_SIZE(archivers); i++) { - if (!strcmp(name, archivers[i].name)) { - memset(ar, 0, sizeof(*ar)); - ar->name = archivers[i].name; - ar->write_archive = archivers[i].write_archive; - ar->parse_extra = archivers[i].parse_extra; - rv = 0; - break; - } + if (!strcmp(name, archivers[i].name)) + return &archivers[i]; } - return rv; + return NULL; } void parse_pathspec_arg(const char **pathspec, struct archiver_args *ar_args) @@ -145,7 +134,8 @@ void parse_treeish_arg(const char **argv, struct archiver_args *ar_args, ar_args->time = archive_time; } -int parse_archive_args(int argc, const char **argv, struct archiver *ar) +int parse_archive_args(int argc, const char **argv, const struct archiver **ar, + struct archiver_args *args) { const char *extra_argv[MAX_EXTRA_ARGS]; int extra_argc = 0; @@ -190,17 +180,18 @@ int parse_archive_args(int argc, const char **argv, struct archiver *ar) /* We need at least one parameter -- tree-ish */ if (argc - 1 < i) usage(archive_usage); - if (init_archiver(format, ar) < 0) + *ar = lookup_archiver(format); + if (!*ar) die("Unknown archive format '%s'", format); if (extra_argc) { - if (!ar->parse_extra) + if (!(*ar)->parse_extra) die("'%s' format does not handle %s", - ar->name, extra_argv[0]); - ar->args.extra = ar->parse_extra(extra_argc, extra_argv); + (*ar)->name, extra_argv[0]); + args->extra = (*ar)->parse_extra(extra_argc, extra_argv); } - ar->args.verbose = verbose; - ar->args.base = base; + args->verbose = verbose; + args->base = base; return i; } @@ -238,7 +229,8 @@ static const char *extract_remote_arg(int *ac, const char **av) int cmd_archive(int argc, const char **argv, const char *prefix) { - struct archiver ar; + const struct archiver *ar = NULL; + struct archiver_args args; int tree_idx; const char *remote = NULL; @@ -248,14 +240,13 @@ int cmd_archive(int argc, const char **argv, const char *prefix) setvbuf(stderr, NULL, _IOLBF, BUFSIZ); - memset(&ar, 0, sizeof(ar)); - tree_idx = parse_archive_args(argc, argv, &ar); + tree_idx = parse_archive_args(argc, argv, &ar, &args); if (prefix == NULL) prefix = setup_git_directory(); argv += tree_idx; - parse_treeish_arg(argv, &ar.args, prefix); - parse_pathspec_arg(argv + 1, &ar.args); + parse_treeish_arg(argv, &args, prefix); + parse_pathspec_arg(argv + 1, &args); - return ar.write_archive(&ar.args); + return ar->write_archive(&args); } diff --git a/builtin-upload-archive.c b/builtin-upload-archive.c index 371400d49a..295e24c2fa 100644 --- a/builtin-upload-archive.c +++ b/builtin-upload-archive.c @@ -19,7 +19,8 @@ static const char lostchild[] = static int run_upload_archive(int argc, const char **argv, const char *prefix) { - struct archiver ar; + const struct archiver *ar; + struct archiver_args args; const char *sent_argv[MAX_ARGS]; const char *arg_cmd = "argument "; char *p, buf[4096]; @@ -65,12 +66,12 @@ static int run_upload_archive(int argc, const char **argv, const char *prefix) sent_argv[sent_argc] = NULL; /* parse all options sent by the client */ - treeish_idx = parse_archive_args(sent_argc, sent_argv, &ar); + treeish_idx = parse_archive_args(sent_argc, sent_argv, &ar, &args); - parse_treeish_arg(sent_argv + treeish_idx, &ar.args, prefix); - parse_pathspec_arg(sent_argv + treeish_idx + 1, &ar.args); + parse_treeish_arg(sent_argv + treeish_idx, &args, prefix); + parse_pathspec_arg(sent_argv + treeish_idx + 1, &args); - return ar.write_archive(&ar.args); + return ar->write_archive(&args); } static void error_clnt(const char *fmt, ...)