]> asedeno.scripts.mit.edu Git - git.git/blob - builtin-for-each-ref.c
74a7337da52ccab6eb25d51eeca4baba486a7a83
[git.git] / builtin-for-each-ref.c
1 #include "builtin.h"
2 #include "cache.h"
3 #include "refs.h"
4 #include "object.h"
5 #include "tag.h"
6 #include "commit.h"
7 #include "tree.h"
8 #include "blob.h"
9 #include "quote.h"
10
11 /* Quoting styles */
12 #define QUOTE_NONE 0
13 #define QUOTE_SHELL 1
14 #define QUOTE_PERL 2
15 #define QUOTE_PYTHON 3
16 #define QUOTE_TCL 4
17
18 typedef enum { FIELD_STR, FIELD_ULONG, FIELD_TIME } cmp_type;
19
20 struct atom_value {
21         const char *s;
22         unsigned long ul; /* used for sorting when not FIELD_STR */
23 };
24
25 struct ref_sort {
26         struct ref_sort *next;
27         int atom; /* index into used_atom array */
28         unsigned reverse : 1;
29 };
30
31 struct refinfo {
32         char *refname;
33         unsigned char objectname[20];
34         struct atom_value *value;
35 };
36
37 static struct {
38         const char *name;
39         cmp_type cmp_type;
40 } valid_atom[] = {
41         { "refname" },
42         { "objecttype" },
43         { "objectsize", FIELD_ULONG },
44         { "objectname" },
45         { "tree" },
46         { "parent" }, /* NEEDSWORK: how to address 2nd and later parents? */
47         { "numparent", FIELD_ULONG },
48         { "object" },
49         { "type" },
50         { "tag" },
51         { "author" },
52         { "authorname" },
53         { "authoremail" },
54         { "authordate", FIELD_TIME },
55         { "committer" },
56         { "committername" },
57         { "committeremail" },
58         { "committerdate", FIELD_TIME },
59         { "tagger" },
60         { "taggername" },
61         { "taggeremail" },
62         { "taggerdate", FIELD_TIME },
63         { "creator" },
64         { "creatordate", FIELD_TIME },
65         { "subject" },
66         { "body" },
67         { "contents" },
68 };
69
70 /*
71  * An atom is a valid field atom listed above, possibly prefixed with
72  * a "*" to denote deref_tag().
73  *
74  * We parse given format string and sort specifiers, and make a list
75  * of properties that we need to extract out of objects.  refinfo
76  * structure will hold an array of values extracted that can be
77  * indexed with the "atom number", which is an index into this
78  * array.
79  */
80 static const char **used_atom;
81 static cmp_type *used_atom_type;
82 static int used_atom_cnt, sort_atom_limit, need_tagged;
83
84 /*
85  * Used to parse format string and sort specifiers
86  */
87 static int parse_atom(const char *atom, const char *ep)
88 {
89         const char *sp;
90         char *n;
91         int i, at;
92
93         sp = atom;
94         if (*sp == '*' && sp < ep)
95                 sp++; /* deref */
96         if (ep <= sp)
97                 die("malformed field name: %.*s", (int)(ep-atom), atom);
98
99         /* Do we have the atom already used elsewhere? */
100         for (i = 0; i < used_atom_cnt; i++) {
101                 int len = strlen(used_atom[i]);
102                 if (len == ep - atom && !memcmp(used_atom[i], atom, len))
103                         return i;
104         }
105
106         /* Is the atom a valid one? */
107         for (i = 0; i < ARRAY_SIZE(valid_atom); i++) {
108                 int len = strlen(valid_atom[i].name);
109                 /*
110                  * If the atom name has a colon, strip it and everything after
111                  * it off - it specifies the format for this entry, and
112                  * shouldn't be used for checking against the valid_atom
113                  * table.
114                  */
115                 const char *formatp = strchr(sp, ':');
116                 if (!formatp)
117                         formatp = ep;
118                 if (len == formatp - sp && !memcmp(valid_atom[i].name, sp, len))
119                         break;
120         }
121
122         if (ARRAY_SIZE(valid_atom) <= i)
123                 die("unknown field name: %.*s", (int)(ep-atom), atom);
124
125         /* Add it in, including the deref prefix */
126         at = used_atom_cnt;
127         used_atom_cnt++;
128         used_atom = xrealloc(used_atom,
129                              (sizeof *used_atom) * used_atom_cnt);
130         used_atom_type = xrealloc(used_atom_type,
131                                   (sizeof(*used_atom_type) * used_atom_cnt));
132         n = xmalloc(ep - atom + 1);
133         memcpy(n, atom, ep - atom);
134         n[ep-atom] = 0;
135         used_atom[at] = n;
136         used_atom_type[at] = valid_atom[i].cmp_type;
137         return at;
138 }
139
140 /*
141  * In a format string, find the next occurrence of %(atom).
142  */
143 static const char *find_next(const char *cp)
144 {
145         while (*cp) {
146                 if (*cp == '%') {
147                         /* %( is the start of an atom;
148                          * %% is a quoted per-cent.
149                          */
150                         if (cp[1] == '(')
151                                 return cp;
152                         else if (cp[1] == '%')
153                                 cp++; /* skip over two % */
154                         /* otherwise this is a singleton, literal % */
155                 }
156                 cp++;
157         }
158         return NULL;
159 }
160
161 /*
162  * Make sure the format string is well formed, and parse out
163  * the used atoms.
164  */
165 static void verify_format(const char *format)
166 {
167         const char *cp, *sp;
168         for (cp = format; *cp && (sp = find_next(cp)); ) {
169                 const char *ep = strchr(sp, ')');
170                 if (!ep)
171                         die("malformatted format string %s", sp);
172                 /* sp points at "%(" and ep points at the closing ")" */
173                 parse_atom(sp + 2, ep);
174                 cp = ep + 1;
175         }
176 }
177
178 /*
179  * Given an object name, read the object data and size, and return a
180  * "struct object".  If the object data we are returning is also borrowed
181  * by the "struct object" representation, set *eaten as well---it is a
182  * signal from parse_object_buffer to us not to free the buffer.
183  */
184 static void *get_obj(const unsigned char *sha1, struct object **obj, unsigned long *sz, int *eaten)
185 {
186         enum object_type type;
187         void *buf = read_sha1_file(sha1, &type, sz);
188
189         if (buf)
190                 *obj = parse_object_buffer(sha1, type, *sz, buf, eaten);
191         else
192                 *obj = NULL;
193         return buf;
194 }
195
196 /* See grab_values */
197 static void grab_common_values(struct atom_value *val, int deref, struct object *obj, void *buf, unsigned long sz)
198 {
199         int i;
200
201         for (i = 0; i < used_atom_cnt; i++) {
202                 const char *name = used_atom[i];
203                 struct atom_value *v = &val[i];
204                 if (!!deref != (*name == '*'))
205                         continue;
206                 if (deref)
207                         name++;
208                 if (!strcmp(name, "objecttype"))
209                         v->s = typename(obj->type);
210                 else if (!strcmp(name, "objectsize")) {
211                         char *s = xmalloc(40);
212                         sprintf(s, "%lu", sz);
213                         v->ul = sz;
214                         v->s = s;
215                 }
216                 else if (!strcmp(name, "objectname")) {
217                         char *s = xmalloc(41);
218                         strcpy(s, sha1_to_hex(obj->sha1));
219                         v->s = s;
220                 }
221         }
222 }
223
224 /* See grab_values */
225 static void grab_tag_values(struct atom_value *val, int deref, struct object *obj, void *buf, unsigned long sz)
226 {
227         int i;
228         struct tag *tag = (struct tag *) obj;
229
230         for (i = 0; i < used_atom_cnt; i++) {
231                 const char *name = used_atom[i];
232                 struct atom_value *v = &val[i];
233                 if (!!deref != (*name == '*'))
234                         continue;
235                 if (deref)
236                         name++;
237                 if (!strcmp(name, "tag"))
238                         v->s = tag->tag;
239         }
240 }
241
242 static int num_parents(struct commit *commit)
243 {
244         struct commit_list *parents;
245         int i;
246
247         for (i = 0, parents = commit->parents;
248              parents;
249              parents = parents->next)
250                 i++;
251         return i;
252 }
253
254 /* See grab_values */
255 static void grab_commit_values(struct atom_value *val, int deref, struct object *obj, void *buf, unsigned long sz)
256 {
257         int i;
258         struct commit *commit = (struct commit *) obj;
259
260         for (i = 0; i < used_atom_cnt; i++) {
261                 const char *name = used_atom[i];
262                 struct atom_value *v = &val[i];
263                 if (!!deref != (*name == '*'))
264                         continue;
265                 if (deref)
266                         name++;
267                 if (!strcmp(name, "tree")) {
268                         char *s = xmalloc(41);
269                         strcpy(s, sha1_to_hex(commit->tree->object.sha1));
270                         v->s = s;
271                 }
272                 if (!strcmp(name, "numparent")) {
273                         char *s = xmalloc(40);
274                         sprintf(s, "%lu", v->ul);
275                         v->s = s;
276                         v->ul = num_parents(commit);
277                 }
278                 else if (!strcmp(name, "parent")) {
279                         int num = num_parents(commit);
280                         int i;
281                         struct commit_list *parents;
282                         char *s = xmalloc(42 * num);
283                         v->s = s;
284                         for (i = 0, parents = commit->parents;
285                              parents;
286                              parents = parents->next, i = i + 42) {
287                                 struct commit *parent = parents->item;
288                                 strcpy(s+i, sha1_to_hex(parent->object.sha1));
289                                 if (parents->next)
290                                         s[i+40] = ' ';
291                         }
292                 }
293         }
294 }
295
296 static const char *find_wholine(const char *who, int wholen, const char *buf, unsigned long sz)
297 {
298         const char *eol;
299         while (*buf) {
300                 if (!strncmp(buf, who, wholen) &&
301                     buf[wholen] == ' ')
302                         return buf + wholen + 1;
303                 eol = strchr(buf, '\n');
304                 if (!eol)
305                         return "";
306                 eol++;
307                 if (eol[1] == '\n')
308                         return ""; /* end of header */
309                 buf = eol;
310         }
311         return "";
312 }
313
314 static const char *copy_line(const char *buf)
315 {
316         const char *eol = strchr(buf, '\n');
317         char *line;
318         int len;
319         if (!eol)
320                 return "";
321         len = eol - buf;
322         line = xmalloc(len + 1);
323         memcpy(line, buf, len);
324         line[len] = 0;
325         return line;
326 }
327
328 static const char *copy_name(const char *buf)
329 {
330         const char *eol = strchr(buf, '\n');
331         const char *eoname = strstr(buf, " <");
332         char *line;
333         int len;
334         if (!(eoname && eol && eoname < eol))
335                 return "";
336         len = eoname - buf;
337         line = xmalloc(len + 1);
338         memcpy(line, buf, len);
339         line[len] = 0;
340         return line;
341 }
342
343 static const char *copy_email(const char *buf)
344 {
345         const char *email = strchr(buf, '<');
346         const char *eoemail = strchr(email, '>');
347         char *line;
348         int len;
349         if (!email || !eoemail)
350                 return "";
351         eoemail++;
352         len = eoemail - email;
353         line = xmalloc(len + 1);
354         memcpy(line, email, len);
355         line[len] = 0;
356         return line;
357 }
358
359 static void grab_date(const char *buf, struct atom_value *v)
360 {
361         const char *eoemail = strstr(buf, "> ");
362         char *zone;
363         unsigned long timestamp;
364         long tz;
365
366         if (!eoemail)
367                 goto bad;
368         timestamp = strtoul(eoemail + 2, &zone, 10);
369         if (timestamp == ULONG_MAX)
370                 goto bad;
371         tz = strtol(zone, NULL, 10);
372         if ((tz == LONG_MIN || tz == LONG_MAX) && errno == ERANGE)
373                 goto bad;
374         v->s = xstrdup(show_date(timestamp, tz, 0));
375         v->ul = timestamp;
376         return;
377  bad:
378         v->s = "";
379         v->ul = 0;
380 }
381
382 /* See grab_values */
383 static void grab_person(const char *who, struct atom_value *val, int deref, struct object *obj, void *buf, unsigned long sz)
384 {
385         int i;
386         int wholen = strlen(who);
387         const char *wholine = NULL;
388
389         for (i = 0; i < used_atom_cnt; i++) {
390                 const char *name = used_atom[i];
391                 struct atom_value *v = &val[i];
392                 if (!!deref != (*name == '*'))
393                         continue;
394                 if (deref)
395                         name++;
396                 if (strncmp(who, name, wholen))
397                         continue;
398                 if (name[wholen] != 0 &&
399                     strcmp(name + wholen, "name") &&
400                     strcmp(name + wholen, "email") &&
401                     strcmp(name + wholen, "date"))
402                         continue;
403                 if (!wholine)
404                         wholine = find_wholine(who, wholen, buf, sz);
405                 if (!wholine)
406                         return; /* no point looking for it */
407                 if (name[wholen] == 0)
408                         v->s = copy_line(wholine);
409                 else if (!strcmp(name + wholen, "name"))
410                         v->s = copy_name(wholine);
411                 else if (!strcmp(name + wholen, "email"))
412                         v->s = copy_email(wholine);
413                 else if (!strcmp(name + wholen, "date"))
414                         grab_date(wholine, v);
415         }
416
417         /* For a tag or a commit object, if "creator" or "creatordate" is
418          * requested, do something special.
419          */
420         if (strcmp(who, "tagger") && strcmp(who, "committer"))
421                 return; /* "author" for commit object is not wanted */
422         if (!wholine)
423                 wholine = find_wholine(who, wholen, buf, sz);
424         if (!wholine)
425                 return;
426         for (i = 0; i < used_atom_cnt; i++) {
427                 const char *name = used_atom[i];
428                 struct atom_value *v = &val[i];
429                 if (!!deref != (*name == '*'))
430                         continue;
431                 if (deref)
432                         name++;
433
434                 if (!strcmp(name, "creatordate"))
435                         grab_date(wholine, v);
436                 else if (!strcmp(name, "creator"))
437                         v->s = copy_line(wholine);
438         }
439 }
440
441 static void find_subpos(const char *buf, unsigned long sz, const char **sub, const char **body)
442 {
443         while (*buf) {
444                 const char *eol = strchr(buf, '\n');
445                 if (!eol)
446                         return;
447                 if (eol[1] == '\n') {
448                         buf = eol + 1;
449                         break; /* found end of header */
450                 }
451                 buf = eol + 1;
452         }
453         while (*buf == '\n')
454                 buf++;
455         if (!*buf)
456                 return;
457         *sub = buf; /* first non-empty line */
458         buf = strchr(buf, '\n');
459         if (!buf)
460                 return; /* no body */
461         while (*buf == '\n')
462                 buf++; /* skip blank between subject and body */
463         *body = buf;
464 }
465
466 /* See grab_values */
467 static void grab_sub_body_contents(struct atom_value *val, int deref, struct object *obj, void *buf, unsigned long sz)
468 {
469         int i;
470         const char *subpos = NULL, *bodypos = NULL;
471
472         for (i = 0; i < used_atom_cnt; i++) {
473                 const char *name = used_atom[i];
474                 struct atom_value *v = &val[i];
475                 if (!!deref != (*name == '*'))
476                         continue;
477                 if (deref)
478                         name++;
479                 if (strcmp(name, "subject") &&
480                     strcmp(name, "body") &&
481                     strcmp(name, "contents"))
482                         continue;
483                 if (!subpos)
484                         find_subpos(buf, sz, &subpos, &bodypos);
485                 if (!subpos)
486                         return;
487
488                 if (!strcmp(name, "subject"))
489                         v->s = copy_line(subpos);
490                 else if (!strcmp(name, "body"))
491                         v->s = xstrdup(bodypos);
492                 else if (!strcmp(name, "contents"))
493                         v->s = xstrdup(subpos);
494         }
495 }
496
497 /* We want to have empty print-string for field requests
498  * that do not apply (e.g. "authordate" for a tag object)
499  */
500 static void fill_missing_values(struct atom_value *val)
501 {
502         int i;
503         for (i = 0; i < used_atom_cnt; i++) {
504                 struct atom_value *v = &val[i];
505                 if (v->s == NULL)
506                         v->s = "";
507         }
508 }
509
510 /*
511  * val is a list of atom_value to hold returned values.  Extract
512  * the values for atoms in used_atom array out of (obj, buf, sz).
513  * when deref is false, (obj, buf, sz) is the object that is
514  * pointed at by the ref itself; otherwise it is the object the
515  * ref (which is a tag) refers to.
516  */
517 static void grab_values(struct atom_value *val, int deref, struct object *obj, void *buf, unsigned long sz)
518 {
519         grab_common_values(val, deref, obj, buf, sz);
520         switch (obj->type) {
521         case OBJ_TAG:
522                 grab_tag_values(val, deref, obj, buf, sz);
523                 grab_sub_body_contents(val, deref, obj, buf, sz);
524                 grab_person("tagger", val, deref, obj, buf, sz);
525                 break;
526         case OBJ_COMMIT:
527                 grab_commit_values(val, deref, obj, buf, sz);
528                 grab_sub_body_contents(val, deref, obj, buf, sz);
529                 grab_person("author", val, deref, obj, buf, sz);
530                 grab_person("committer", val, deref, obj, buf, sz);
531                 break;
532         case OBJ_TREE:
533                 // grab_tree_values(val, deref, obj, buf, sz);
534                 break;
535         case OBJ_BLOB:
536                 // grab_blob_values(val, deref, obj, buf, sz);
537                 break;
538         default:
539                 die("Eh?  Object of type %d?", obj->type);
540         }
541 }
542
543 /*
544  * Parse the object referred by ref, and grab needed value.
545  */
546 static void populate_value(struct refinfo *ref)
547 {
548         void *buf;
549         struct object *obj;
550         int eaten, i;
551         unsigned long size;
552         const unsigned char *tagged;
553
554         ref->value = xcalloc(sizeof(struct atom_value), used_atom_cnt);
555
556         buf = get_obj(ref->objectname, &obj, &size, &eaten);
557         if (!buf)
558                 die("missing object %s for %s",
559                     sha1_to_hex(ref->objectname), ref->refname);
560         if (!obj)
561                 die("parse_object_buffer failed on %s for %s",
562                     sha1_to_hex(ref->objectname), ref->refname);
563
564         /* Fill in specials first */
565         for (i = 0; i < used_atom_cnt; i++) {
566                 const char *name = used_atom[i];
567                 struct atom_value *v = &ref->value[i];
568                 if (!strcmp(name, "refname"))
569                         v->s = ref->refname;
570                 else if (!strcmp(name, "*refname")) {
571                         int len = strlen(ref->refname);
572                         char *s = xmalloc(len + 4);
573                         sprintf(s, "%s^{}", ref->refname);
574                         v->s = s;
575                 }
576         }
577
578         grab_values(ref->value, 0, obj, buf, size);
579         if (!eaten)
580                 free(buf);
581
582         /* If there is no atom that wants to know about tagged
583          * object, we are done.
584          */
585         if (!need_tagged || (obj->type != OBJ_TAG))
586                 return;
587
588         /* If it is a tag object, see if we use a value that derefs
589          * the object, and if we do grab the object it refers to.
590          */
591         tagged = ((struct tag *)obj)->tagged->sha1;
592
593         /* NEEDSWORK: This derefs tag only once, which
594          * is good to deal with chains of trust, but
595          * is not consistent with what deref_tag() does
596          * which peels the onion to the core.
597          */
598         buf = get_obj(tagged, &obj, &size, &eaten);
599         if (!buf)
600                 die("missing object %s for %s",
601                     sha1_to_hex(tagged), ref->refname);
602         if (!obj)
603                 die("parse_object_buffer failed on %s for %s",
604                     sha1_to_hex(tagged), ref->refname);
605         grab_values(ref->value, 1, obj, buf, size);
606         if (!eaten)
607                 free(buf);
608 }
609
610 /*
611  * Given a ref, return the value for the atom.  This lazily gets value
612  * out of the object by calling populate value.
613  */
614 static void get_value(struct refinfo *ref, int atom, struct atom_value **v)
615 {
616         if (!ref->value) {
617                 populate_value(ref);
618                 fill_missing_values(ref->value);
619         }
620         *v = &ref->value[atom];
621 }
622
623 struct grab_ref_cbdata {
624         struct refinfo **grab_array;
625         const char **grab_pattern;
626         int grab_cnt;
627 };
628
629 /*
630  * A call-back given to for_each_ref().  It is unfortunate that we
631  * need to use global variables to pass extra information to this
632  * function.
633  */
634 static int grab_single_ref(const char *refname, const unsigned char *sha1, int flag, void *cb_data)
635 {
636         struct grab_ref_cbdata *cb = cb_data;
637         struct refinfo *ref;
638         int cnt;
639
640         if (*cb->grab_pattern) {
641                 const char **pattern;
642                 int namelen = strlen(refname);
643                 for (pattern = cb->grab_pattern; *pattern; pattern++) {
644                         const char *p = *pattern;
645                         int plen = strlen(p);
646
647                         if ((plen <= namelen) &&
648                             !strncmp(refname, p, plen) &&
649                             (refname[plen] == '\0' ||
650                              refname[plen] == '/'))
651                                 break;
652                         if (!fnmatch(p, refname, FNM_PATHNAME))
653                                 break;
654                 }
655                 if (!*pattern)
656                         return 0;
657         }
658
659         /* We do not open the object yet; sort may only need refname
660          * to do its job and the resulting list may yet to be pruned
661          * by maxcount logic.
662          */
663         ref = xcalloc(1, sizeof(*ref));
664         ref->refname = xstrdup(refname);
665         hashcpy(ref->objectname, sha1);
666
667         cnt = cb->grab_cnt;
668         cb->grab_array = xrealloc(cb->grab_array,
669                                   sizeof(*cb->grab_array) * (cnt + 1));
670         cb->grab_array[cnt++] = ref;
671         cb->grab_cnt = cnt;
672         return 0;
673 }
674
675 static int cmp_ref_sort(struct ref_sort *s, struct refinfo *a, struct refinfo *b)
676 {
677         struct atom_value *va, *vb;
678         int cmp;
679         cmp_type cmp_type = used_atom_type[s->atom];
680
681         get_value(a, s->atom, &va);
682         get_value(b, s->atom, &vb);
683         switch (cmp_type) {
684         case FIELD_STR:
685                 cmp = strcmp(va->s, vb->s);
686                 break;
687         default:
688                 if (va->ul < vb->ul)
689                         cmp = -1;
690                 else if (va->ul == vb->ul)
691                         cmp = 0;
692                 else
693                         cmp = 1;
694                 break;
695         }
696         return (s->reverse) ? -cmp : cmp;
697 }
698
699 static struct ref_sort *ref_sort;
700 static int compare_refs(const void *a_, const void *b_)
701 {
702         struct refinfo *a = *((struct refinfo **)a_);
703         struct refinfo *b = *((struct refinfo **)b_);
704         struct ref_sort *s;
705
706         for (s = ref_sort; s; s = s->next) {
707                 int cmp = cmp_ref_sort(s, a, b);
708                 if (cmp)
709                         return cmp;
710         }
711         return 0;
712 }
713
714 static void sort_refs(struct ref_sort *sort, struct refinfo **refs, int num_refs)
715 {
716         ref_sort = sort;
717         qsort(refs, num_refs, sizeof(struct refinfo *), compare_refs);
718 }
719
720 static void print_value(struct refinfo *ref, int atom, int quote_style)
721 {
722         struct atom_value *v;
723         get_value(ref, atom, &v);
724         switch (quote_style) {
725         case QUOTE_NONE:
726                 fputs(v->s, stdout);
727                 break;
728         case QUOTE_SHELL:
729                 sq_quote_print(stdout, v->s);
730                 break;
731         case QUOTE_PERL:
732                 perl_quote_print(stdout, v->s);
733                 break;
734         case QUOTE_PYTHON:
735                 python_quote_print(stdout, v->s);
736                 break;
737         case QUOTE_TCL:
738                 tcl_quote_print(stdout, v->s);
739                 break;
740         }
741 }
742
743 static int hex1(char ch)
744 {
745         if ('0' <= ch && ch <= '9')
746                 return ch - '0';
747         else if ('a' <= ch && ch <= 'f')
748                 return ch - 'a' + 10;
749         else if ('A' <= ch && ch <= 'F')
750                 return ch - 'A' + 10;
751         return -1;
752 }
753 static int hex2(const char *cp)
754 {
755         if (cp[0] && cp[1])
756                 return (hex1(cp[0]) << 4) | hex1(cp[1]);
757         else
758                 return -1;
759 }
760
761 static void emit(const char *cp, const char *ep)
762 {
763         while (*cp && (!ep || cp < ep)) {
764                 if (*cp == '%') {
765                         if (cp[1] == '%')
766                                 cp++;
767                         else {
768                                 int ch = hex2(cp + 1);
769                                 if (0 <= ch) {
770                                         putchar(ch);
771                                         cp += 3;
772                                         continue;
773                                 }
774                         }
775                 }
776                 putchar(*cp);
777                 cp++;
778         }
779 }
780
781 static void show_ref(struct refinfo *info, const char *format, int quote_style)
782 {
783         const char *cp, *sp, *ep;
784
785         for (cp = format; *cp && (sp = find_next(cp)); cp = ep + 1) {
786                 ep = strchr(sp, ')');
787                 if (cp < sp)
788                         emit(cp, sp);
789                 print_value(info, parse_atom(sp + 2, ep), quote_style);
790         }
791         if (*cp) {
792                 sp = cp + strlen(cp);
793                 emit(cp, sp);
794         }
795         putchar('\n');
796 }
797
798 static struct ref_sort *default_sort(void)
799 {
800         static const char cstr_name[] = "refname";
801
802         struct ref_sort *sort = xcalloc(1, sizeof(*sort));
803
804         sort->next = NULL;
805         sort->atom = parse_atom(cstr_name, cstr_name + strlen(cstr_name));
806         return sort;
807 }
808
809 int cmd_for_each_ref(int ac, const char **av, const char *prefix)
810 {
811         int i, num_refs;
812         const char *format = NULL;
813         struct ref_sort *sort = NULL, **sort_tail = &sort;
814         int maxcount = 0;
815         int quote_style = -1; /* unspecified yet */
816         struct refinfo **refs;
817         struct grab_ref_cbdata cbdata;
818
819         for (i = 1; i < ac; i++) {
820                 const char *arg = av[i];
821                 if (arg[0] != '-')
822                         break;
823                 if (!strcmp(arg, "--")) {
824                         i++;
825                         break;
826                 }
827                 if (!prefixcmp(arg, "--format=")) {
828                         if (format)
829                                 die("more than one --format?");
830                         format = arg + 9;
831                         continue;
832                 }
833                 if (!strcmp(arg, "-s") || !strcmp(arg, "--shell") ) {
834                         if (0 <= quote_style)
835                                 die("more than one quoting style?");
836                         quote_style = QUOTE_SHELL;
837                         continue;
838                 }
839                 if (!strcmp(arg, "-p") || !strcmp(arg, "--perl") ) {
840                         if (0 <= quote_style)
841                                 die("more than one quoting style?");
842                         quote_style = QUOTE_PERL;
843                         continue;
844                 }
845                 if (!strcmp(arg, "--python") ) {
846                         if (0 <= quote_style)
847                                 die("more than one quoting style?");
848                         quote_style = QUOTE_PYTHON;
849                         continue;
850                 }
851                 if (!strcmp(arg, "--tcl") ) {
852                         if (0 <= quote_style)
853                                 die("more than one quoting style?");
854                         quote_style = QUOTE_TCL;
855                         continue;
856                 }
857                 if (!prefixcmp(arg, "--count=")) {
858                         if (maxcount)
859                                 die("more than one --count?");
860                         maxcount = atoi(arg + 8);
861                         if (maxcount <= 0)
862                                 die("The number %s did not parse", arg);
863                         continue;
864                 }
865                 if (!prefixcmp(arg, "--sort=")) {
866                         struct ref_sort *s = xcalloc(1, sizeof(*s));
867                         int len;
868
869                         s->next = NULL;
870                         *sort_tail = s;
871                         sort_tail = &s->next;
872
873                         arg += 7;
874                         if (*arg == '-') {
875                                 s->reverse = 1;
876                                 arg++;
877                         }
878                         len = strlen(arg);
879                         sort->atom = parse_atom(arg, arg+len);
880                         continue;
881                 }
882                 break;
883         }
884         if (quote_style < 0)
885                 quote_style = QUOTE_NONE;
886
887         if (!sort)
888                 sort = default_sort();
889         sort_atom_limit = used_atom_cnt;
890         if (!format)
891                 format = "%(objectname) %(objecttype)\t%(refname)";
892
893         verify_format(format);
894
895         memset(&cbdata, 0, sizeof(cbdata));
896         cbdata.grab_pattern = av + i;
897         for_each_ref(grab_single_ref, &cbdata);
898         refs = cbdata.grab_array;
899         num_refs = cbdata.grab_cnt;
900
901         for (i = 0; i < used_atom_cnt; i++) {
902                 if (used_atom[i][0] == '*') {
903                         need_tagged = 1;
904                         break;
905                 }
906         }
907
908         sort_refs(sort, refs, num_refs);
909
910         if (!maxcount || num_refs < maxcount)
911                 maxcount = num_refs;
912         for (i = 0; i < maxcount; i++)
913                 show_ref(refs[i], format, quote_style);
914         return 0;
915 }