Code

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