diff options
Diffstat (limited to 'builtin/cat-file.c')
-rw-r--r-- | builtin/cat-file.c | 133 |
1 files changed, 66 insertions, 67 deletions
diff --git a/builtin/cat-file.c b/builtin/cat-file.c index 0bafc14e6c..694c8538df 100644 --- a/builtin/cat-file.c +++ b/builtin/cat-file.c @@ -4,11 +4,9 @@ * Copyright (C) Linus Torvalds, 2005 */ #define USE_THE_INDEX_VARIABLE -#include "cache.h" -#include "alloc.h" +#include "builtin.h" #include "config.h" #include "convert.h" -#include "builtin.h" #include "diff.h" #include "environment.h" #include "gettext.h" @@ -22,7 +20,7 @@ #include "packfile.h" #include "object-file.h" #include "object-name.h" -#include "object-store.h" +#include "object-store-ll.h" #include "replace-object.h" #include "promisor-remote.h" #include "mailmap.h" @@ -42,7 +40,8 @@ struct batch_options { int all_objects; int unordered; int transform_mode; /* may be 'w' or 'c' for --filters or --textconv */ - int nul_terminated; + char input_delim; + char output_delim; const char *format; }; @@ -309,10 +308,8 @@ static int is_atom(const char *atom, const char *s, int slen) } static void expand_atom(struct strbuf *sb, const char *atom, int len, - void *vdata) + struct expand_data *data) { - struct expand_data *data = vdata; - if (is_atom("objectname", atom, len)) { if (!data->mark_query) strbuf_addstr(sb, oid_to_hex(&data->oid)); @@ -346,19 +343,21 @@ static void expand_atom(struct strbuf *sb, const char *atom, int len, die("unknown format element: %.*s", len, atom); } -static size_t expand_format(struct strbuf *sb, const char *start, void *data) +static void expand_format(struct strbuf *sb, const char *start, + struct expand_data *data) { - const char *end; - - if (*start != '(') - return 0; - end = strchr(start + 1, ')'); - if (!end) - die("format element '%s' does not end in ')'", start); - - expand_atom(sb, start + 1, end - start - 1, data); - - return end - start + 1; + while (strbuf_expand_step(sb, &start)) { + const char *end; + + if (skip_prefix(start, "%", &start) || *start != '(') + strbuf_addch(sb, '%'); + else if (!(end = strchr(start + 1, ')'))) + die("format element '%s' does not end in ')'", start); + else { + expand_atom(sb, start + 1, end - start - 1, data); + start = end + 1; + } + } } static void batch_write(struct batch_options *opt, const void *data, int len) @@ -437,11 +436,12 @@ static void print_object_or_die(struct batch_options *opt, struct expand_data *d } } -static void print_default_format(struct strbuf *scratch, struct expand_data *data) +static void print_default_format(struct strbuf *scratch, struct expand_data *data, + struct batch_options *opt) { - strbuf_addf(scratch, "%s %s %"PRIuMAX"\n", oid_to_hex(&data->oid), + strbuf_addf(scratch, "%s %s %"PRIuMAX"%c", oid_to_hex(&data->oid), type_name(data->type), - (uintmax_t)data->size); + (uintmax_t)data->size, opt->output_delim); } /* @@ -470,8 +470,8 @@ static void batch_object_write(const char *obj_name, &data->oid, &data->info, OBJECT_INFO_LOOKUP_REPLACE); if (ret < 0) { - printf("%s missing\n", - obj_name ? obj_name : oid_to_hex(&data->oid)); + printf("%s missing%c", + obj_name ? obj_name : oid_to_hex(&data->oid), opt->output_delim); fflush(stdout); return; } @@ -492,17 +492,17 @@ static void batch_object_write(const char *obj_name, strbuf_reset(scratch); if (!opt->format) { - print_default_format(scratch, data); + print_default_format(scratch, data, opt); } else { - strbuf_expand(scratch, opt->format, expand_format, data); - strbuf_addch(scratch, '\n'); + expand_format(scratch, opt->format, data); + strbuf_addch(scratch, opt->output_delim); } batch_write(opt, scratch->buf, scratch->len); if (opt->batch_mode == BATCH_MODE_CONTENTS) { print_object_or_die(opt, data); - batch_write(opt, "\n", 1); + batch_write(opt, &opt->output_delim, 1); } } @@ -520,22 +520,25 @@ static void batch_one_object(const char *obj_name, if (result != FOUND) { switch (result) { case MISSING_OBJECT: - printf("%s missing\n", obj_name); + printf("%s missing%c", obj_name, opt->output_delim); break; case SHORT_NAME_AMBIGUOUS: - printf("%s ambiguous\n", obj_name); + printf("%s ambiguous%c", obj_name, opt->output_delim); break; case DANGLING_SYMLINK: - printf("dangling %"PRIuMAX"\n%s\n", - (uintmax_t)strlen(obj_name), obj_name); + printf("dangling %"PRIuMAX"%c%s%c", + (uintmax_t)strlen(obj_name), + opt->output_delim, obj_name, opt->output_delim); break; case SYMLINK_LOOP: - printf("loop %"PRIuMAX"\n%s\n", - (uintmax_t)strlen(obj_name), obj_name); + printf("loop %"PRIuMAX"%c%s%c", + (uintmax_t)strlen(obj_name), + opt->output_delim, obj_name, opt->output_delim); break; case NOT_DIR: - printf("notdir %"PRIuMAX"\n%s\n", - (uintmax_t)strlen(obj_name), obj_name); + printf("notdir %"PRIuMAX"%c%s%c", + (uintmax_t)strlen(obj_name), + opt->output_delim, obj_name, opt->output_delim); break; default: BUG("unknown get_sha1_with_context result %d\n", @@ -547,9 +550,9 @@ static void batch_one_object(const char *obj_name, } if (ctx.mode == 0) { - printf("symlink %"PRIuMAX"\n%s\n", + printf("symlink %"PRIuMAX"%c%s%c", (uintmax_t)ctx.symlink_path.len, - ctx.symlink_path.buf); + opt->output_delim, ctx.symlink_path.buf, opt->output_delim); fflush(stdout); return; } @@ -694,20 +697,12 @@ static void batch_objects_command(struct batch_options *opt, struct queued_cmd *queued_cmd = NULL; size_t alloc = 0, nr = 0; - while (1) { - int i, ret; + while (strbuf_getdelim_strip_crlf(&input, stdin, opt->input_delim) != EOF) { + int i; const struct parse_cmd *cmd = NULL; const char *p = NULL, *cmd_end; struct queued_cmd call = {0}; - if (opt->nul_terminated) - ret = strbuf_getline_nul(&input, stdin); - else - ret = strbuf_getline(&input, stdin); - - if (ret) - break; - if (!input.len) die(_("empty command in input")); if (isspace(*input.buf)) @@ -777,9 +772,8 @@ static int batch_objects(struct batch_options *opt) */ memset(&data, 0, sizeof(data)); data.mark_query = 1; - strbuf_expand(&output, + expand_format(&output, opt->format ? opt->format : DEFAULT_FORMAT, - expand_format, &data); data.mark_query = 0; strbuf_release(&output); @@ -805,7 +799,7 @@ static int batch_objects(struct batch_options *opt) if (repo_has_promisor_remote(the_repository)) warning("This repository uses promisor remotes. Some objects may not be loaded."); - read_replace_refs = 0; + disable_replace_refs(); cb.opt = opt; cb.expand = &data; @@ -851,16 +845,7 @@ static int batch_objects(struct batch_options *opt) goto cleanup; } - while (1) { - int ret; - if (opt->nul_terminated) - ret = strbuf_getline_nul(&input, stdin); - else - ret = strbuf_getline(&input, stdin); - - if (ret == EOF) - break; - + while (strbuf_getdelim_strip_crlf(&input, stdin, opt->input_delim) != EOF) { if (data.split_on_whitespace) { /* * Split at first whitespace, tying off the beginning @@ -885,12 +870,13 @@ static int batch_objects(struct batch_options *opt) return retval; } -static int git_cat_file_config(const char *var, const char *value, void *cb) +static int git_cat_file_config(const char *var, const char *value, + const struct config_context *ctx, void *cb) { if (userdiff_config(var, value) < 0) return -1; - return git_default_config(var, value, cb); + return git_default_config(var, value, ctx, cb); } static int batch_option_callback(const struct option *opt, @@ -929,6 +915,8 @@ int cmd_cat_file(int argc, const char **argv, const char *prefix) const char *exp_type = NULL, *obj_name = NULL; struct batch_options batch = {0}; int unknown_type = 0; + int input_nul_terminated = 0; + int nul_terminated = 0; const char * const usage[] = { N_("git cat-file <type> <object>"), @@ -936,7 +924,7 @@ int cmd_cat_file(int argc, const char **argv, const char *prefix) N_("git cat-file (-t | -s) [--allow-unknown-type] <object>"), N_("git cat-file (--batch | --batch-check | --batch-command) [--batch-all-objects]\n" " [--buffer] [--follow-symlinks] [--unordered]\n" - " [--textconv | --filters] [-z]"), + " [--textconv | --filters] [-Z]"), N_("git cat-file (--textconv | --filters)\n" " [<rev>:<path|tree-ish> | --path=<path|tree-ish> <rev>]"), NULL @@ -965,7 +953,9 @@ int cmd_cat_file(int argc, const char **argv, const char *prefix) N_("like --batch, but don't emit <contents>"), PARSE_OPT_OPTARG | PARSE_OPT_NONEG, batch_option_callback), - OPT_BOOL('z', NULL, &batch.nul_terminated, N_("stdin is NUL-terminated")), + OPT_BOOL_F('z', NULL, &input_nul_terminated, N_("stdin is NUL-terminated"), + PARSE_OPT_HIDDEN), + OPT_BOOL('Z', NULL, &nul_terminated, N_("stdin and stdout is NUL-terminated")), OPT_CALLBACK_F(0, "batch-command", &batch, N_("format"), N_("read commands from stdin"), PARSE_OPT_OPTARG | PARSE_OPT_NONEG, @@ -1024,9 +1014,18 @@ int cmd_cat_file(int argc, const char **argv, const char *prefix) else if (batch.all_objects) usage_msg_optf(_("'%s' requires a batch mode"), usage, options, "--batch-all-objects"); - else if (batch.nul_terminated) + else if (input_nul_terminated) usage_msg_optf(_("'%s' requires a batch mode"), usage, options, "-z"); + else if (nul_terminated) + usage_msg_optf(_("'%s' requires a batch mode"), usage, options, + "-Z"); + + batch.input_delim = batch.output_delim = '\n'; + if (input_nul_terminated) + batch.input_delim = '\0'; + if (nul_terminated) + batch.input_delim = batch.output_delim = '\0'; /* Batch defaults */ if (batch.buffer_output < 0) |