114
return 0;
115
}
116
117
+struct expand_data {
118
+ unsigned char sha1[20];
119
+ enum object_type type;
120
+ unsigned long size;
121
+
122
+ /*
123
+ * If mark_query is true, we do not expand anything, but rather
124
+ * just mark the object_info with items we wish to query.
125
+ */
126
+ int mark_query;
127
+
128
+ /*
129
+ * After a mark_query run, this object_info is set up to be
130
+ * passed to sha1_object_info_extended. It will point to the data
131
+ * elements above, so you can retrieve the response from there.
132
+ */
133
+ struct object_info info;
134
+};
135
+
136
+static int is_atom(const char *atom, const char *s, int slen)
137
+{
138
+ int alen = strlen(atom);
139
+ return alen == slen && !memcmp(atom, s, alen);
140
+}
141
+
142
+static void expand_atom(struct strbuf *sb, const char *atom, int len,
143
+ void *vdata)
144
+{
145
+ struct expand_data *data = vdata;
146
+
147
+ if (is_atom("objectname", atom, len)) {
148
+ if (!data->mark_query)
149
+ strbuf_addstr(sb, sha1_to_hex(data->sha1));
150
+ } else if (is_atom("objecttype", atom, len)) {
151
+ if (!data->mark_query)
152
+ strbuf_addstr(sb, typename(data->type));
153
+ } else if (is_atom("objectsize", atom, len)) {
154
+ if (data->mark_query)
155
+ data->info.sizep = &data->size;
156
+ else
157
+ strbuf_addf(sb, "%lu", data->size);
158
+ } else
159
+ die("unknown format element: %.*s", len, atom);
160
+}
161
+
162
+static size_t expand_format(struct strbuf *sb, const char *start, void *data)
163
+{
164
+ const char *end;
165
+
166
+ if (*start != '(')
167
+ return 0;
168
+ end = strchr(start + 1, ')');
169
+ if (!end)
170
+ die("format element '%s' does not end in ')'", start);
171
+
172
+ expand_atom(sb, start + 1, end - start - 1, data);
173
+
174
+ return end - start + 1;
175
+}
176
+
177
static void print_object_or_die(int fd, const unsigned char *sha1,
178
enum object_type type, unsigned long size)
179
{
202
struct batch_options {
203
int enabled;
204
int print_contents;
205
+ const char *format;
206
};
207
147
-static int batch_one_object(const char *obj_name, struct batch_options *opt)
208
+static int batch_one_object(const char *obj_name, struct batch_options *opt,
209
+ struct expand_data *data)
210
{
149
- unsigned char sha1[20];
150
- enum object_type type = 0;
151
- unsigned long size;
211
+ struct strbuf buf = STRBUF_INIT;
212
213
if (!obj_name)
214
return 1;
215
156
- if (get_sha1(obj_name, sha1)) {
216
+ if (get_sha1(obj_name, data->sha1)) {
217
printf("%s missing\n", obj_name);
218
fflush(stdout);
219
return 0;
220
}
221
162
- type = sha1_object_info(sha1, &size);
163
- if (type <= 0) {
222
+ data->type = sha1_object_info_extended(data->sha1, &data->info);
223
+ if (data->type <= 0) {
224
printf("%s missing\n", obj_name);
225
fflush(stdout);
226
return 0;
227
}
228
169
- printf("%s %s %lu\n", sha1_to_hex(sha1), typename(type), size);
170
- fflush(stdout);
229
+ strbuf_expand(&buf, opt->format, expand_format, data);
230
+ strbuf_addch(&buf, '\n');
231
+ write_or_die(1, buf.buf, buf.len);
232
+ strbuf_release(&buf);
233
234
if (opt->print_contents) {
173
- print_object_or_die(1, sha1, type, size);
235
+ print_object_or_die(1, data->sha1, data->type, data->size);
236
write_or_die(1, "\n", 1);
237
}
238
return 0;
241
static int batch_objects(struct batch_options *opt)
242
{
243
struct strbuf buf = STRBUF_INIT;
244
+ struct expand_data data;
245
+
246
+ if (!opt->format)
247
+ opt->format = "%(objectname) %(objecttype) %(objectsize)";
248
+
249
+ /*
250
+ * Expand once with our special mark_query flag, which will prime the
251
+ * object_info to be handed to sha1_object_info_extended for each
252
+ * object.
253
+ */
254
+ memset(&data, 0, sizeof(data));
255
+ data.mark_query = 1;
256
+ strbuf_expand(&buf, opt->format, expand_format, &data);
257
+ data.mark_query = 0;
258
259
while (strbuf_getline(&buf, stdin, '\n') != EOF) {
184
- int error = batch_one_object(buf.buf, opt);
260
+ int error = batch_one_object(buf.buf, opt, &data);
261
if (error)
262
return error;
263
}
292
293
bo->enabled = 1;
294
bo->print_contents = !strcmp(opt->long_name, "batch");
295
+ bo->format = arg;
296
297
return 0;
298
}
312
OPT_SET_INT('p', NULL, &opt, N_("pretty-print object's content"), 'p'),
313
OPT_SET_INT(0, "textconv", &opt,
314
N_("for blob objects, run textconv on object's content"), 'c'),
238
- { OPTION_CALLBACK, 0, "batch", &batch, NULL,
315
+ { OPTION_CALLBACK, 0, "batch", &batch, "format",
316
N_("show info and content of objects fed from the standard input"),
240
- PARSE_OPT_NOARG, batch_option_callback },
241
- { OPTION_CALLBACK, 0, "batch-check", &batch, NULL,
317
+ PARSE_OPT_OPTARG, batch_option_callback },
318
+ { OPTION_CALLBACK, 0, "batch-check", &batch, "format",
319
N_("show info about objects fed from the standard input"),
243
- PARSE_OPT_NOARG, batch_option_callback },
320
+ PARSE_OPT_OPTARG, batch_option_callback },
321
OPT_END()
322
};
323