Thread-safe xmalloc and xrealloc needs a recursive mutex
[git/dscho.git] / builtin-for-each-ref.c
bloba5a83f14693b94adf3ae0dbc1b500b2e6b2be54d
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 #include "parse-options.h"
11 #include "remote.h"
13 /* Quoting styles */
14 #define QUOTE_NONE 0
15 #define QUOTE_SHELL 1
16 #define QUOTE_PERL 2
17 #define QUOTE_PYTHON 4
18 #define QUOTE_TCL 8
20 typedef enum { FIELD_STR, FIELD_ULONG, FIELD_TIME } cmp_type;
22 struct atom_value {
23         const char *s;
24         unsigned long ul; /* used for sorting when not FIELD_STR */
27 struct ref_sort {
28         struct ref_sort *next;
29         int atom; /* index into used_atom array */
30         unsigned reverse : 1;
33 struct refinfo {
34         char *refname;
35         unsigned char objectname[20];
36         struct atom_value *value;
39 static struct {
40         const char *name;
41         cmp_type cmp_type;
42 } valid_atom[] = {
43         { "refname" },
44         { "objecttype" },
45         { "objectsize", FIELD_ULONG },
46         { "objectname" },
47         { "tree" },
48         { "parent" },
49         { "numparent", FIELD_ULONG },
50         { "object" },
51         { "type" },
52         { "tag" },
53         { "author" },
54         { "authorname" },
55         { "authoremail" },
56         { "authordate", FIELD_TIME },
57         { "committer" },
58         { "committername" },
59         { "committeremail" },
60         { "committerdate", FIELD_TIME },
61         { "tagger" },
62         { "taggername" },
63         { "taggeremail" },
64         { "taggerdate", FIELD_TIME },
65         { "creator" },
66         { "creatordate", FIELD_TIME },
67         { "subject" },
68         { "body" },
69         { "contents" },
70         { "upstream" },
74  * An atom is a valid field atom listed above, possibly prefixed with
75  * a "*" to denote deref_tag().
76  *
77  * We parse given format string and sort specifiers, and make a list
78  * of properties that we need to extract out of objects.  refinfo
79  * structure will hold an array of values extracted that can be
80  * indexed with the "atom number", which is an index into this
81  * array.
82  */
83 static const char **used_atom;
84 static cmp_type *used_atom_type;
85 static int used_atom_cnt, sort_atom_limit, need_tagged;
88  * Used to parse format string and sort specifiers
89  */
90 static int parse_atom(const char *atom, const char *ep)
92         const char *sp;
93         int i, at;
95         sp = atom;
96         if (*sp == '*' && sp < ep)
97                 sp++; /* deref */
98         if (ep <= sp)
99                 die("malformed field name: %.*s", (int)(ep-atom), atom);
101         /* Do we have the atom already used elsewhere? */
102         for (i = 0; i < used_atom_cnt; i++) {
103                 int len = strlen(used_atom[i]);
104                 if (len == ep - atom && !memcmp(used_atom[i], atom, len))
105                         return i;
106         }
108         /* Is the atom a valid one? */
109         for (i = 0; i < ARRAY_SIZE(valid_atom); i++) {
110                 int len = strlen(valid_atom[i].name);
111                 /*
112                  * If the atom name has a colon, strip it and everything after
113                  * it off - it specifies the format for this entry, and
114                  * shouldn't be used for checking against the valid_atom
115                  * table.
116                  */
117                 const char *formatp = strchr(sp, ':');
118                 if (!formatp || ep < formatp)
119                         formatp = ep;
120                 if (len == formatp - sp && !memcmp(valid_atom[i].name, sp, len))
121                         break;
122         }
124         if (ARRAY_SIZE(valid_atom) <= i)
125                 die("unknown field name: %.*s", (int)(ep-atom), atom);
127         /* Add it in, including the deref prefix */
128         at = used_atom_cnt;
129         used_atom_cnt++;
130         used_atom = xrealloc(used_atom,
131                              (sizeof *used_atom) * used_atom_cnt);
132         used_atom_type = xrealloc(used_atom_type,
133                                   (sizeof(*used_atom_type) * used_atom_cnt));
134         used_atom[at] = xmemdupz(atom, ep - atom);
135         used_atom_type[at] = valid_atom[i].cmp_type;
136         return at;
140  * In a format string, find the next occurrence of %(atom).
141  */
142 static const char *find_next(const char *cp)
144         while (*cp) {
145                 if (*cp == '%') {
146                         /* %( is the start of an atom;
147                          * %% is a quoted per-cent.
148                          */
149                         if (cp[1] == '(')
150                                 return cp;
151                         else if (cp[1] == '%')
152                                 cp++; /* skip over two % */
153                         /* otherwise this is a singleton, literal % */
154                 }
155                 cp++;
156         }
157         return NULL;
161  * Make sure the format string is well formed, and parse out
162  * the used atoms.
163  */
164 static int verify_format(const char *format)
166         const char *cp, *sp;
167         for (cp = format; *cp && (sp = find_next(cp)); ) {
168                 const char *ep = strchr(sp, ')');
169                 if (!ep)
170                         return error("malformed format string %s", sp);
171                 /* sp points at "%(" and ep points at the closing ")" */
172                 parse_atom(sp + 2, ep);
173                 cp = ep + 1;
174         }
175         return 0;
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)
186         enum object_type type;
187         void *buf = read_sha1_file(sha1, &type, sz);
189         if (buf)
190                 *obj = parse_object_buffer(sha1, type, *sz, buf, eaten);
191         else
192                 *obj = NULL;
193         return buf;
196 /* See grab_values */
197 static void grab_common_values(struct atom_value *val, int deref, struct object *obj, void *buf, unsigned long sz)
199         int i;
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         }
224 /* See grab_values */
225 static void grab_tag_values(struct atom_value *val, int deref, struct object *obj, void *buf, unsigned long sz)
227         int i;
228         struct tag *tag = (struct tag *) obj;
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                 else if (!strcmp(name, "type") && tag->tagged)
240                         v->s = typename(tag->tagged->type);
241                 else if (!strcmp(name, "object") && tag->tagged) {
242                         char *s = xmalloc(41);
243                         strcpy(s, sha1_to_hex(tag->tagged->sha1));
244                         v->s = s;
245                 }
246         }
249 static int num_parents(struct commit *commit)
251         struct commit_list *parents;
252         int i;
254         for (i = 0, parents = commit->parents;
255              parents;
256              parents = parents->next)
257                 i++;
258         return i;
261 /* See grab_values */
262 static void grab_commit_values(struct atom_value *val, int deref, struct object *obj, void *buf, unsigned long sz)
264         int i;
265         struct commit *commit = (struct commit *) obj;
267         for (i = 0; i < used_atom_cnt; i++) {
268                 const char *name = used_atom[i];
269                 struct atom_value *v = &val[i];
270                 if (!!deref != (*name == '*'))
271                         continue;
272                 if (deref)
273                         name++;
274                 if (!strcmp(name, "tree")) {
275                         char *s = xmalloc(41);
276                         strcpy(s, sha1_to_hex(commit->tree->object.sha1));
277                         v->s = s;
278                 }
279                 if (!strcmp(name, "numparent")) {
280                         char *s = xmalloc(40);
281                         v->ul = num_parents(commit);
282                         sprintf(s, "%lu", v->ul);
283                         v->s = s;
284                 }
285                 else if (!strcmp(name, "parent")) {
286                         int num = num_parents(commit);
287                         int i;
288                         struct commit_list *parents;
289                         char *s = xmalloc(41 * num + 1);
290                         v->s = s;
291                         for (i = 0, parents = commit->parents;
292                              parents;
293                              parents = parents->next, i = i + 41) {
294                                 struct commit *parent = parents->item;
295                                 strcpy(s+i, sha1_to_hex(parent->object.sha1));
296                                 if (parents->next)
297                                         s[i+40] = ' ';
298                         }
299                         if (!i)
300                                 *s = '\0';
301                 }
302         }
305 static const char *find_wholine(const char *who, int wholen, const char *buf, unsigned long sz)
307         const char *eol;
308         while (*buf) {
309                 if (!strncmp(buf, who, wholen) &&
310                     buf[wholen] == ' ')
311                         return buf + wholen + 1;
312                 eol = strchr(buf, '\n');
313                 if (!eol)
314                         return "";
315                 eol++;
316                 if (*eol == '\n')
317                         return ""; /* end of header */
318                 buf = eol;
319         }
320         return "";
323 static const char *copy_line(const char *buf)
325         const char *eol = strchrnul(buf, '\n');
326         return xmemdupz(buf, eol - buf);
329 static const char *copy_name(const char *buf)
331         const char *cp;
332         for (cp = buf; *cp && *cp != '\n'; cp++) {
333                 if (!strncmp(cp, " <", 2))
334                         return xmemdupz(buf, cp - buf);
335         }
336         return "";
339 static const char *copy_email(const char *buf)
341         const char *email = strchr(buf, '<');
342         const char *eoemail;
343         if (!email)
344                 return "";
345         eoemail = strchr(email, '>');
346         if (!eoemail)
347                 return "";
348         return xmemdupz(email, eoemail + 1 - email);
351 static void grab_date(const char *buf, struct atom_value *v, const char *atomname)
353         const char *eoemail = strstr(buf, "> ");
354         char *zone;
355         unsigned long timestamp;
356         long tz;
357         enum date_mode date_mode = DATE_NORMAL;
358         const char *formatp;
360         /*
361          * We got here because atomname ends in "date" or "date<something>";
362          * it's not possible that <something> is not ":<format>" because
363          * parse_atom() wouldn't have allowed it, so we can assume that no
364          * ":" means no format is specified, and use the default.
365          */
366         formatp = strchr(atomname, ':');
367         if (formatp != NULL) {
368                 formatp++;
369                 date_mode = parse_date_format(formatp);
370         }
372         if (!eoemail)
373                 goto bad;
374         timestamp = strtoul(eoemail + 2, &zone, 10);
375         if (timestamp == ULONG_MAX)
376                 goto bad;
377         tz = strtol(zone, NULL, 10);
378         if ((tz == LONG_MIN || tz == LONG_MAX) && errno == ERANGE)
379                 goto bad;
380         v->s = xstrdup(show_date(timestamp, tz, date_mode));
381         v->ul = timestamp;
382         return;
383  bad:
384         v->s = "";
385         v->ul = 0;
388 /* See grab_values */
389 static void grab_person(const char *who, struct atom_value *val, int deref, struct object *obj, void *buf, unsigned long sz)
391         int i;
392         int wholen = strlen(who);
393         const char *wholine = NULL;
395         for (i = 0; i < used_atom_cnt; i++) {
396                 const char *name = used_atom[i];
397                 struct atom_value *v = &val[i];
398                 if (!!deref != (*name == '*'))
399                         continue;
400                 if (deref)
401                         name++;
402                 if (strncmp(who, name, wholen))
403                         continue;
404                 if (name[wholen] != 0 &&
405                     strcmp(name + wholen, "name") &&
406                     strcmp(name + wholen, "email") &&
407                     prefixcmp(name + wholen, "date"))
408                         continue;
409                 if (!wholine)
410                         wholine = find_wholine(who, wholen, buf, sz);
411                 if (!wholine)
412                         return; /* no point looking for it */
413                 if (name[wholen] == 0)
414                         v->s = copy_line(wholine);
415                 else if (!strcmp(name + wholen, "name"))
416                         v->s = copy_name(wholine);
417                 else if (!strcmp(name + wholen, "email"))
418                         v->s = copy_email(wholine);
419                 else if (!prefixcmp(name + wholen, "date"))
420                         grab_date(wholine, v, name);
421         }
423         /* For a tag or a commit object, if "creator" or "creatordate" is
424          * requested, do something special.
425          */
426         if (strcmp(who, "tagger") && strcmp(who, "committer"))
427                 return; /* "author" for commit object is not wanted */
428         if (!wholine)
429                 wholine = find_wholine(who, wholen, buf, sz);
430         if (!wholine)
431                 return;
432         for (i = 0; i < used_atom_cnt; i++) {
433                 const char *name = used_atom[i];
434                 struct atom_value *v = &val[i];
435                 if (!!deref != (*name == '*'))
436                         continue;
437                 if (deref)
438                         name++;
440                 if (!prefixcmp(name, "creatordate"))
441                         grab_date(wholine, v, name);
442                 else if (!strcmp(name, "creator"))
443                         v->s = copy_line(wholine);
444         }
447 static void find_subpos(const char *buf, unsigned long sz, const char **sub, const char **body)
449         while (*buf) {
450                 const char *eol = strchr(buf, '\n');
451                 if (!eol)
452                         return;
453                 if (eol[1] == '\n') {
454                         buf = eol + 1;
455                         break; /* found end of header */
456                 }
457                 buf = eol + 1;
458         }
459         while (*buf == '\n')
460                 buf++;
461         if (!*buf)
462                 return;
463         *sub = buf; /* first non-empty line */
464         buf = strchr(buf, '\n');
465         if (!buf) {
466                 *body = "";
467                 return; /* no body */
468         }
469         while (*buf == '\n')
470                 buf++; /* skip blank between subject and body */
471         *body = buf;
474 /* See grab_values */
475 static void grab_sub_body_contents(struct atom_value *val, int deref, struct object *obj, void *buf, unsigned long sz)
477         int i;
478         const char *subpos = NULL, *bodypos = NULL;
480         for (i = 0; i < used_atom_cnt; i++) {
481                 const char *name = used_atom[i];
482                 struct atom_value *v = &val[i];
483                 if (!!deref != (*name == '*'))
484                         continue;
485                 if (deref)
486                         name++;
487                 if (strcmp(name, "subject") &&
488                     strcmp(name, "body") &&
489                     strcmp(name, "contents"))
490                         continue;
491                 if (!subpos)
492                         find_subpos(buf, sz, &subpos, &bodypos);
493                 if (!subpos)
494                         return;
496                 if (!strcmp(name, "subject"))
497                         v->s = copy_line(subpos);
498                 else if (!strcmp(name, "body"))
499                         v->s = xstrdup(bodypos);
500                 else if (!strcmp(name, "contents"))
501                         v->s = xstrdup(subpos);
502         }
505 /* We want to have empty print-string for field requests
506  * that do not apply (e.g. "authordate" for a tag object)
507  */
508 static void fill_missing_values(struct atom_value *val)
510         int i;
511         for (i = 0; i < used_atom_cnt; i++) {
512                 struct atom_value *v = &val[i];
513                 if (v->s == NULL)
514                         v->s = "";
515         }
519  * val is a list of atom_value to hold returned values.  Extract
520  * the values for atoms in used_atom array out of (obj, buf, sz).
521  * when deref is false, (obj, buf, sz) is the object that is
522  * pointed at by the ref itself; otherwise it is the object the
523  * ref (which is a tag) refers to.
524  */
525 static void grab_values(struct atom_value *val, int deref, struct object *obj, void *buf, unsigned long sz)
527         grab_common_values(val, deref, obj, buf, sz);
528         switch (obj->type) {
529         case OBJ_TAG:
530                 grab_tag_values(val, deref, obj, buf, sz);
531                 grab_sub_body_contents(val, deref, obj, buf, sz);
532                 grab_person("tagger", val, deref, obj, buf, sz);
533                 break;
534         case OBJ_COMMIT:
535                 grab_commit_values(val, deref, obj, buf, sz);
536                 grab_sub_body_contents(val, deref, obj, buf, sz);
537                 grab_person("author", val, deref, obj, buf, sz);
538                 grab_person("committer", val, deref, obj, buf, sz);
539                 break;
540         case OBJ_TREE:
541                 // grab_tree_values(val, deref, obj, buf, sz);
542                 break;
543         case OBJ_BLOB:
544                 // grab_blob_values(val, deref, obj, buf, sz);
545                 break;
546         default:
547                 die("Eh?  Object of type %d?", obj->type);
548         }
552  * Parse the object referred by ref, and grab needed value.
553  */
554 static void populate_value(struct refinfo *ref)
556         void *buf;
557         struct object *obj;
558         int eaten, i;
559         unsigned long size;
560         const unsigned char *tagged;
562         ref->value = xcalloc(sizeof(struct atom_value), used_atom_cnt);
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                 int deref = 0;
569                 const char *refname;
570                 const char *formatp;
572                 if (*name == '*') {
573                         deref = 1;
574                         name++;
575                 }
577                 if (!prefixcmp(name, "refname"))
578                         refname = ref->refname;
579                 else if (!prefixcmp(name, "upstream")) {
580                         struct branch *branch;
581                         /* only local branches may have an upstream */
582                         if (prefixcmp(ref->refname, "refs/heads/"))
583                                 continue;
584                         branch = branch_get(ref->refname + 11);
586                         if (!branch || !branch->merge || !branch->merge[0] ||
587                             !branch->merge[0]->dst)
588                                 continue;
589                         refname = branch->merge[0]->dst;
590                 }
591                 else
592                         continue;
594                 formatp = strchr(name, ':');
595                 /* look for "short" refname format */
596                 if (formatp) {
597                         formatp++;
598                         if (!strcmp(formatp, "short"))
599                                 refname = shorten_unambiguous_ref(refname,
600                                                       warn_ambiguous_refs);
601                         else
602                                 die("unknown %.*s format %s",
603                                     (int)(formatp - name), name, formatp);
604                 }
606                 if (!deref)
607                         v->s = refname;
608                 else {
609                         int len = strlen(refname);
610                         char *s = xmalloc(len + 4);
611                         sprintf(s, "%s^{}", refname);
612                         v->s = s;
613                 }
614         }
616         for (i = 0; i < used_atom_cnt; i++) {
617                 struct atom_value *v = &ref->value[i];
618                 if (v->s == NULL)
619                         goto need_obj;
620         }
621         return;
623  need_obj:
624         buf = get_obj(ref->objectname, &obj, &size, &eaten);
625         if (!buf)
626                 die("missing object %s for %s",
627                     sha1_to_hex(ref->objectname), ref->refname);
628         if (!obj)
629                 die("parse_object_buffer failed on %s for %s",
630                     sha1_to_hex(ref->objectname), ref->refname);
632         grab_values(ref->value, 0, obj, buf, size);
633         if (!eaten)
634                 free(buf);
636         /* If there is no atom that wants to know about tagged
637          * object, we are done.
638          */
639         if (!need_tagged || (obj->type != OBJ_TAG))
640                 return;
642         /* If it is a tag object, see if we use a value that derefs
643          * the object, and if we do grab the object it refers to.
644          */
645         tagged = ((struct tag *)obj)->tagged->sha1;
647         /* NEEDSWORK: This derefs tag only once, which
648          * is good to deal with chains of trust, but
649          * is not consistent with what deref_tag() does
650          * which peels the onion to the core.
651          */
652         buf = get_obj(tagged, &obj, &size, &eaten);
653         if (!buf)
654                 die("missing object %s for %s",
655                     sha1_to_hex(tagged), ref->refname);
656         if (!obj)
657                 die("parse_object_buffer failed on %s for %s",
658                     sha1_to_hex(tagged), ref->refname);
659         grab_values(ref->value, 1, obj, buf, size);
660         if (!eaten)
661                 free(buf);
665  * Given a ref, return the value for the atom.  This lazily gets value
666  * out of the object by calling populate value.
667  */
668 static void get_value(struct refinfo *ref, int atom, struct atom_value **v)
670         if (!ref->value) {
671                 populate_value(ref);
672                 fill_missing_values(ref->value);
673         }
674         *v = &ref->value[atom];
677 struct grab_ref_cbdata {
678         struct refinfo **grab_array;
679         const char **grab_pattern;
680         int grab_cnt;
684  * A call-back given to for_each_ref().  It is unfortunate that we
685  * need to use global variables to pass extra information to this
686  * function.
687  */
688 static int grab_single_ref(const char *refname, const unsigned char *sha1, int flag, void *cb_data)
690         struct grab_ref_cbdata *cb = cb_data;
691         struct refinfo *ref;
692         int cnt;
694         if (*cb->grab_pattern) {
695                 const char **pattern;
696                 int namelen = strlen(refname);
697                 for (pattern = cb->grab_pattern; *pattern; pattern++) {
698                         const char *p = *pattern;
699                         int plen = strlen(p);
701                         if ((plen <= namelen) &&
702                             !strncmp(refname, p, plen) &&
703                             (refname[plen] == '\0' ||
704                              refname[plen] == '/' ||
705                              p[plen-1] == '/'))
706                                 break;
707                         if (!fnmatch(p, refname, FNM_PATHNAME))
708                                 break;
709                 }
710                 if (!*pattern)
711                         return 0;
712         }
714         /* We do not open the object yet; sort may only need refname
715          * to do its job and the resulting list may yet to be pruned
716          * by maxcount logic.
717          */
718         ref = xcalloc(1, sizeof(*ref));
719         ref->refname = xstrdup(refname);
720         hashcpy(ref->objectname, sha1);
722         cnt = cb->grab_cnt;
723         cb->grab_array = xrealloc(cb->grab_array,
724                                   sizeof(*cb->grab_array) * (cnt + 1));
725         cb->grab_array[cnt++] = ref;
726         cb->grab_cnt = cnt;
727         return 0;
730 static int cmp_ref_sort(struct ref_sort *s, struct refinfo *a, struct refinfo *b)
732         struct atom_value *va, *vb;
733         int cmp;
734         cmp_type cmp_type = used_atom_type[s->atom];
736         get_value(a, s->atom, &va);
737         get_value(b, s->atom, &vb);
738         switch (cmp_type) {
739         case FIELD_STR:
740                 cmp = strcmp(va->s, vb->s);
741                 break;
742         default:
743                 if (va->ul < vb->ul)
744                         cmp = -1;
745                 else if (va->ul == vb->ul)
746                         cmp = 0;
747                 else
748                         cmp = 1;
749                 break;
750         }
751         return (s->reverse) ? -cmp : cmp;
754 static struct ref_sort *ref_sort;
755 static int compare_refs(const void *a_, const void *b_)
757         struct refinfo *a = *((struct refinfo **)a_);
758         struct refinfo *b = *((struct refinfo **)b_);
759         struct ref_sort *s;
761         for (s = ref_sort; s; s = s->next) {
762                 int cmp = cmp_ref_sort(s, a, b);
763                 if (cmp)
764                         return cmp;
765         }
766         return 0;
769 static void sort_refs(struct ref_sort *sort, struct refinfo **refs, int num_refs)
771         ref_sort = sort;
772         qsort(refs, num_refs, sizeof(struct refinfo *), compare_refs);
775 static void print_value(struct refinfo *ref, int atom, int quote_style)
777         struct atom_value *v;
778         get_value(ref, atom, &v);
779         switch (quote_style) {
780         case QUOTE_NONE:
781                 fputs(v->s, stdout);
782                 break;
783         case QUOTE_SHELL:
784                 sq_quote_print(stdout, v->s);
785                 break;
786         case QUOTE_PERL:
787                 perl_quote_print(stdout, v->s);
788                 break;
789         case QUOTE_PYTHON:
790                 python_quote_print(stdout, v->s);
791                 break;
792         case QUOTE_TCL:
793                 tcl_quote_print(stdout, v->s);
794                 break;
795         }
798 static int hex1(char ch)
800         if ('0' <= ch && ch <= '9')
801                 return ch - '0';
802         else if ('a' <= ch && ch <= 'f')
803                 return ch - 'a' + 10;
804         else if ('A' <= ch && ch <= 'F')
805                 return ch - 'A' + 10;
806         return -1;
808 static int hex2(const char *cp)
810         if (cp[0] && cp[1])
811                 return (hex1(cp[0]) << 4) | hex1(cp[1]);
812         else
813                 return -1;
816 static void emit(const char *cp, const char *ep)
818         while (*cp && (!ep || cp < ep)) {
819                 if (*cp == '%') {
820                         if (cp[1] == '%')
821                                 cp++;
822                         else {
823                                 int ch = hex2(cp + 1);
824                                 if (0 <= ch) {
825                                         putchar(ch);
826                                         cp += 3;
827                                         continue;
828                                 }
829                         }
830                 }
831                 putchar(*cp);
832                 cp++;
833         }
836 static void show_ref(struct refinfo *info, const char *format, int quote_style)
838         const char *cp, *sp, *ep;
840         for (cp = format; *cp && (sp = find_next(cp)); cp = ep + 1) {
841                 ep = strchr(sp, ')');
842                 if (cp < sp)
843                         emit(cp, sp);
844                 print_value(info, parse_atom(sp + 2, ep), quote_style);
845         }
846         if (*cp) {
847                 sp = cp + strlen(cp);
848                 emit(cp, sp);
849         }
850         putchar('\n');
853 static struct ref_sort *default_sort(void)
855         static const char cstr_name[] = "refname";
857         struct ref_sort *sort = xcalloc(1, sizeof(*sort));
859         sort->next = NULL;
860         sort->atom = parse_atom(cstr_name, cstr_name + strlen(cstr_name));
861         return sort;
864 static int opt_parse_sort(const struct option *opt, const char *arg, int unset)
866         struct ref_sort **sort_tail = opt->value;
867         struct ref_sort *s;
868         int len;
870         if (!arg) /* should --no-sort void the list ? */
871                 return -1;
873         *sort_tail = s = xcalloc(1, sizeof(*s));
875         if (*arg == '-') {
876                 s->reverse = 1;
877                 arg++;
878         }
879         len = strlen(arg);
880         s->atom = parse_atom(arg, arg+len);
881         return 0;
884 static char const * const for_each_ref_usage[] = {
885         "git for-each-ref [options] [<pattern>]",
886         NULL
889 int cmd_for_each_ref(int argc, const char **argv, const char *prefix)
891         int i, num_refs;
892         const char *format = "%(objectname) %(objecttype)\t%(refname)";
893         struct ref_sort *sort = NULL, **sort_tail = &sort;
894         int maxcount = 0, quote_style = 0;
895         struct refinfo **refs;
896         struct grab_ref_cbdata cbdata;
898         struct option opts[] = {
899                 OPT_BIT('s', "shell", &quote_style,
900                         "quote placeholders suitably for shells", QUOTE_SHELL),
901                 OPT_BIT('p', "perl",  &quote_style,
902                         "quote placeholders suitably for perl", QUOTE_PERL),
903                 OPT_BIT(0 , "python", &quote_style,
904                         "quote placeholders suitably for python", QUOTE_PYTHON),
905                 OPT_BIT(0 , "tcl",  &quote_style,
906                         "quote placeholders suitably for tcl", QUOTE_TCL),
908                 OPT_GROUP(""),
909                 OPT_INTEGER( 0 , "count", &maxcount, "show only <n> matched refs"),
910                 OPT_STRING(  0 , "format", &format, "format", "format to use for the output"),
911                 OPT_CALLBACK(0 , "sort", sort_tail, "key",
912                             "field name to sort on", &opt_parse_sort),
913                 OPT_END(),
914         };
916         parse_options(argc, argv, prefix, opts, for_each_ref_usage, 0);
917         if (maxcount < 0) {
918                 error("invalid --count argument: `%d'", maxcount);
919                 usage_with_options(for_each_ref_usage, opts);
920         }
921         if (HAS_MULTI_BITS(quote_style)) {
922                 error("more than one quoting style?");
923                 usage_with_options(for_each_ref_usage, opts);
924         }
925         if (verify_format(format))
926                 usage_with_options(for_each_ref_usage, opts);
928         if (!sort)
929                 sort = default_sort();
930         sort_atom_limit = used_atom_cnt;
932         /* for warn_ambiguous_refs */
933         git_config(git_default_config, NULL);
935         memset(&cbdata, 0, sizeof(cbdata));
936         cbdata.grab_pattern = argv;
937         for_each_rawref(grab_single_ref, &cbdata);
938         refs = cbdata.grab_array;
939         num_refs = cbdata.grab_cnt;
941         for (i = 0; i < used_atom_cnt; i++) {
942                 if (used_atom[i][0] == '*') {
943                         need_tagged = 1;
944                         break;
945                 }
946         }
948         sort_refs(sort, refs, num_refs);
950         if (!maxcount || num_refs < maxcount)
951                 maxcount = num_refs;
952         for (i = 0; i < maxcount; i++)
953                 show_ref(refs[i], format, quote_style);
954         return 0;