ref-filter: introduce refname_atom_parser_internal()
[git] / ref-filter.c
1 #include "builtin.h"
2 #include "cache.h"
3 #include "parse-options.h"
4 #include "refs.h"
5 #include "wildmatch.h"
6 #include "commit.h"
7 #include "remote.h"
8 #include "color.h"
9 #include "tag.h"
10 #include "quote.h"
11 #include "ref-filter.h"
12 #include "revision.h"
13 #include "utf8.h"
14 #include "git-compat-util.h"
15 #include "version.h"
16 #include "trailer.h"
17 #include "wt-status.h"
18
19 typedef enum { FIELD_STR, FIELD_ULONG, FIELD_TIME } cmp_type;
20 typedef enum { COMPARE_EQUAL, COMPARE_UNEQUAL, COMPARE_NONE } cmp_status;
21
22 struct align {
23         align_type position;
24         unsigned int width;
25 };
26
27 struct if_then_else {
28         cmp_status cmp_status;
29         const char *str;
30         unsigned int then_atom_seen : 1,
31                 else_atom_seen : 1,
32                 condition_satisfied : 1;
33 };
34
35 struct refname_atom {
36         enum { R_NORMAL, R_SHORT, R_STRIP } option;
37         unsigned int strip;
38 };
39
40 /*
41  * An atom is a valid field atom listed below, possibly prefixed with
42  * a "*" to denote deref_tag().
43  *
44  * We parse given format string and sort specifiers, and make a list
45  * of properties that we need to extract out of objects.  ref_array_item
46  * structure will hold an array of values extracted that can be
47  * indexed with the "atom number", which is an index into this
48  * array.
49  */
50 static struct used_atom {
51         const char *name;
52         cmp_type type;
53         union {
54                 char color[COLOR_MAXLEN];
55                 struct align align;
56                 struct {
57                         enum { RR_NORMAL, RR_SHORTEN, RR_TRACK, RR_TRACKSHORT } option;
58                         unsigned int nobracket : 1;
59                 } remote_ref;
60                 struct {
61                         enum { C_BARE, C_BODY, C_BODY_DEP, C_LINES, C_SIG, C_SUB, C_TRAILERS } option;
62                         unsigned int nlines;
63                 } contents;
64                 struct {
65                         cmp_status cmp_status;
66                         const char *str;
67                 } if_then_else;
68                 struct {
69                         enum { O_FULL, O_LENGTH, O_SHORT } option;
70                         unsigned int length;
71                 } objectname;
72                 struct refname_atom refname;
73         } u;
74 } *used_atom;
75 static int used_atom_cnt, need_tagged, need_symref;
76 static int need_color_reset_at_eol;
77
78 static void color_atom_parser(struct used_atom *atom, const char *color_value)
79 {
80         if (!color_value)
81                 die(_("expected format: %%(color:<color>)"));
82         if (color_parse(color_value, atom->u.color) < 0)
83                 die(_("unrecognized color: %%(color:%s)"), color_value);
84 }
85
86 static void refname_atom_parser_internal(struct refname_atom *atom,
87                                          const char *arg, const char *name)
88 {
89         if (!arg)
90                 atom->option = R_NORMAL;
91         else if (!strcmp(arg, "short"))
92                 atom->option = R_SHORT;
93         else if (skip_prefix(arg, "strip=", &arg)) {
94                 atom->option = R_STRIP;
95                 if (strtoul_ui(arg, 10, &atom->strip) || atom->strip <= 0)
96                         die(_("positive value expected refname:strip=%s"), arg);
97         } else
98                 die(_("unrecognized %%(%s) argument: %s"), name, arg);
99 }
100
101 static void remote_ref_atom_parser(struct used_atom *atom, const char *arg)
102 {
103         struct string_list params = STRING_LIST_INIT_DUP;
104         int i;
105
106         if (!arg) {
107                 atom->u.remote_ref.option = RR_NORMAL;
108                 return;
109         }
110
111         atom->u.remote_ref.nobracket = 0;
112         string_list_split(&params, arg, ',', -1);
113
114         for (i = 0; i < params.nr; i++) {
115                 const char *s = params.items[i].string;
116
117                 if (!strcmp(s, "short"))
118                         atom->u.remote_ref.option = RR_SHORTEN;
119                 else if (!strcmp(s, "track"))
120                         atom->u.remote_ref.option = RR_TRACK;
121                 else if (!strcmp(s, "trackshort"))
122                         atom->u.remote_ref.option = RR_TRACKSHORT;
123                 else if (!strcmp(s, "nobracket"))
124                         atom->u.remote_ref.nobracket = 1;
125                 else
126                         die(_("unrecognized format: %%(%s)"), atom->name);
127         }
128
129         string_list_clear(&params, 0);
130 }
131
132 static void body_atom_parser(struct used_atom *atom, const char *arg)
133 {
134         if (arg)
135                 die(_("%%(body) does not take arguments"));
136         atom->u.contents.option = C_BODY_DEP;
137 }
138
139 static void subject_atom_parser(struct used_atom *atom, const char *arg)
140 {
141         if (arg)
142                 die(_("%%(subject) does not take arguments"));
143         atom->u.contents.option = C_SUB;
144 }
145
146 static void trailers_atom_parser(struct used_atom *atom, const char *arg)
147 {
148         if (arg)
149                 die(_("%%(trailers) does not take arguments"));
150         atom->u.contents.option = C_TRAILERS;
151 }
152
153 static void contents_atom_parser(struct used_atom *atom, const char *arg)
154 {
155         if (!arg)
156                 atom->u.contents.option = C_BARE;
157         else if (!strcmp(arg, "body"))
158                 atom->u.contents.option = C_BODY;
159         else if (!strcmp(arg, "signature"))
160                 atom->u.contents.option = C_SIG;
161         else if (!strcmp(arg, "subject"))
162                 atom->u.contents.option = C_SUB;
163         else if (!strcmp(arg, "trailers"))
164                 atom->u.contents.option = C_TRAILERS;
165         else if (skip_prefix(arg, "lines=", &arg)) {
166                 atom->u.contents.option = C_LINES;
167                 if (strtoul_ui(arg, 10, &atom->u.contents.nlines))
168                         die(_("positive value expected contents:lines=%s"), arg);
169         } else
170                 die(_("unrecognized %%(contents) argument: %s"), arg);
171 }
172
173 static void objectname_atom_parser(struct used_atom *atom, const char *arg)
174 {
175         if (!arg)
176                 atom->u.objectname.option = O_FULL;
177         else if (!strcmp(arg, "short"))
178                 atom->u.objectname.option = O_SHORT;
179         else if (skip_prefix(arg, "short=", &arg)) {
180                 atom->u.objectname.option = O_LENGTH;
181                 if (strtoul_ui(arg, 10, &atom->u.objectname.length) ||
182                     atom->u.objectname.length == 0)
183                         die(_("positive value expected objectname:short=%s"), arg);
184                 if (atom->u.objectname.length < MINIMUM_ABBREV)
185                         atom->u.objectname.length = MINIMUM_ABBREV;
186         } else
187                 die(_("unrecognized %%(objectname) argument: %s"), arg);
188 }
189
190 static align_type parse_align_position(const char *s)
191 {
192         if (!strcmp(s, "right"))
193                 return ALIGN_RIGHT;
194         else if (!strcmp(s, "middle"))
195                 return ALIGN_MIDDLE;
196         else if (!strcmp(s, "left"))
197                 return ALIGN_LEFT;
198         return -1;
199 }
200
201 static void align_atom_parser(struct used_atom *atom, const char *arg)
202 {
203         struct align *align = &atom->u.align;
204         struct string_list params = STRING_LIST_INIT_DUP;
205         int i;
206         unsigned int width = ~0U;
207
208         if (!arg)
209                 die(_("expected format: %%(align:<width>,<position>)"));
210
211         align->position = ALIGN_LEFT;
212
213         string_list_split(&params, arg, ',', -1);
214         for (i = 0; i < params.nr; i++) {
215                 const char *s = params.items[i].string;
216                 int position;
217
218                 if (skip_prefix(s, "position=", &s)) {
219                         position = parse_align_position(s);
220                         if (position < 0)
221                                 die(_("unrecognized position:%s"), s);
222                         align->position = position;
223                 } else if (skip_prefix(s, "width=", &s)) {
224                         if (strtoul_ui(s, 10, &width))
225                                 die(_("unrecognized width:%s"), s);
226                 } else if (!strtoul_ui(s, 10, &width))
227                         ;
228                 else if ((position = parse_align_position(s)) >= 0)
229                         align->position = position;
230                 else
231                         die(_("unrecognized %%(align) argument: %s"), s);
232         }
233
234         if (width == ~0U)
235                 die(_("positive width expected with the %%(align) atom"));
236         align->width = width;
237         string_list_clear(&params, 0);
238 }
239
240 static void if_atom_parser(struct used_atom *atom, const char *arg)
241 {
242         if (!arg) {
243                 atom->u.if_then_else.cmp_status = COMPARE_NONE;
244                 return;
245         } else if (skip_prefix(arg, "equals=", &atom->u.if_then_else.str)) {
246                 atom->u.if_then_else.cmp_status = COMPARE_EQUAL;
247         } else if (skip_prefix(arg, "notequals=", &atom->u.if_then_else.str)) {
248                 atom->u.if_then_else.cmp_status = COMPARE_UNEQUAL;
249         } else {
250                 die(_("unrecognized %%(if) argument: %s"), arg);
251         }
252 }
253
254
255 static struct {
256         const char *name;
257         cmp_type cmp_type;
258         void (*parser)(struct used_atom *atom, const char *arg);
259 } valid_atom[] = {
260         { "refname" },
261         { "objecttype" },
262         { "objectsize", FIELD_ULONG },
263         { "objectname", FIELD_STR, objectname_atom_parser },
264         { "tree" },
265         { "parent" },
266         { "numparent", FIELD_ULONG },
267         { "object" },
268         { "type" },
269         { "tag" },
270         { "author" },
271         { "authorname" },
272         { "authoremail" },
273         { "authordate", FIELD_TIME },
274         { "committer" },
275         { "committername" },
276         { "committeremail" },
277         { "committerdate", FIELD_TIME },
278         { "tagger" },
279         { "taggername" },
280         { "taggeremail" },
281         { "taggerdate", FIELD_TIME },
282         { "creator" },
283         { "creatordate", FIELD_TIME },
284         { "subject", FIELD_STR, subject_atom_parser },
285         { "body", FIELD_STR, body_atom_parser },
286         { "trailers", FIELD_STR, trailers_atom_parser },
287         { "contents", FIELD_STR, contents_atom_parser },
288         { "upstream", FIELD_STR, remote_ref_atom_parser },
289         { "push", FIELD_STR, remote_ref_atom_parser },
290         { "symref" },
291         { "flag" },
292         { "HEAD" },
293         { "color", FIELD_STR, color_atom_parser },
294         { "align", FIELD_STR, align_atom_parser },
295         { "end" },
296         { "if", FIELD_STR, if_atom_parser },
297         { "then" },
298         { "else" },
299 };
300
301 #define REF_FORMATTING_STATE_INIT  { 0, NULL }
302
303 struct ref_formatting_stack {
304         struct ref_formatting_stack *prev;
305         struct strbuf output;
306         void (*at_end)(struct ref_formatting_stack **stack);
307         void *at_end_data;
308 };
309
310 struct ref_formatting_state {
311         int quote_style;
312         struct ref_formatting_stack *stack;
313 };
314
315 struct atom_value {
316         const char *s;
317         void (*handler)(struct atom_value *atomv, struct ref_formatting_state *state);
318         unsigned long ul; /* used for sorting when not FIELD_STR */
319         struct used_atom *atom;
320 };
321
322 /*
323  * Used to parse format string and sort specifiers
324  */
325 int parse_ref_filter_atom(const char *atom, const char *ep)
326 {
327         const char *sp;
328         const char *arg;
329         int i, at, atom_len;
330
331         sp = atom;
332         if (*sp == '*' && sp < ep)
333                 sp++; /* deref */
334         if (ep <= sp)
335                 die(_("malformed field name: %.*s"), (int)(ep-atom), atom);
336
337         /* Do we have the atom already used elsewhere? */
338         for (i = 0; i < used_atom_cnt; i++) {
339                 int len = strlen(used_atom[i].name);
340                 if (len == ep - atom && !memcmp(used_atom[i].name, atom, len))
341                         return i;
342         }
343
344         /*
345          * If the atom name has a colon, strip it and everything after
346          * it off - it specifies the format for this entry, and
347          * shouldn't be used for checking against the valid_atom
348          * table.
349          */
350         arg = memchr(sp, ':', ep - sp);
351         atom_len = (arg ? arg : ep) - sp;
352
353         /* Is the atom a valid one? */
354         for (i = 0; i < ARRAY_SIZE(valid_atom); i++) {
355                 int len = strlen(valid_atom[i].name);
356                 if (len == atom_len && !memcmp(valid_atom[i].name, sp, len))
357                         break;
358         }
359
360         if (ARRAY_SIZE(valid_atom) <= i)
361                 die(_("unknown field name: %.*s"), (int)(ep-atom), atom);
362
363         /* Add it in, including the deref prefix */
364         at = used_atom_cnt;
365         used_atom_cnt++;
366         REALLOC_ARRAY(used_atom, used_atom_cnt);
367         used_atom[at].name = xmemdupz(atom, ep - atom);
368         used_atom[at].type = valid_atom[i].cmp_type;
369         if (arg)
370                 arg = used_atom[at].name + (arg - atom) + 1;
371         memset(&used_atom[at].u, 0, sizeof(used_atom[at].u));
372         if (valid_atom[i].parser)
373                 valid_atom[i].parser(&used_atom[at], arg);
374         if (*atom == '*')
375                 need_tagged = 1;
376         if (!strcmp(valid_atom[i].name, "symref"))
377                 need_symref = 1;
378         return at;
379 }
380
381 static void quote_formatting(struct strbuf *s, const char *str, int quote_style)
382 {
383         switch (quote_style) {
384         case QUOTE_NONE:
385                 strbuf_addstr(s, str);
386                 break;
387         case QUOTE_SHELL:
388                 sq_quote_buf(s, str);
389                 break;
390         case QUOTE_PERL:
391                 perl_quote_buf(s, str);
392                 break;
393         case QUOTE_PYTHON:
394                 python_quote_buf(s, str);
395                 break;
396         case QUOTE_TCL:
397                 tcl_quote_buf(s, str);
398                 break;
399         }
400 }
401
402 static void append_atom(struct atom_value *v, struct ref_formatting_state *state)
403 {
404         /*
405          * Quote formatting is only done when the stack has a single
406          * element. Otherwise quote formatting is done on the
407          * element's entire output strbuf when the %(end) atom is
408          * encountered.
409          */
410         if (!state->stack->prev)
411                 quote_formatting(&state->stack->output, v->s, state->quote_style);
412         else
413                 strbuf_addstr(&state->stack->output, v->s);
414 }
415
416 static void push_stack_element(struct ref_formatting_stack **stack)
417 {
418         struct ref_formatting_stack *s = xcalloc(1, sizeof(struct ref_formatting_stack));
419
420         strbuf_init(&s->output, 0);
421         s->prev = *stack;
422         *stack = s;
423 }
424
425 static void pop_stack_element(struct ref_formatting_stack **stack)
426 {
427         struct ref_formatting_stack *current = *stack;
428         struct ref_formatting_stack *prev = current->prev;
429
430         if (prev)
431                 strbuf_addbuf(&prev->output, &current->output);
432         strbuf_release(&current->output);
433         free(current);
434         *stack = prev;
435 }
436
437 static void end_align_handler(struct ref_formatting_stack **stack)
438 {
439         struct ref_formatting_stack *cur = *stack;
440         struct align *align = (struct align *)cur->at_end_data;
441         struct strbuf s = STRBUF_INIT;
442
443         strbuf_utf8_align(&s, align->position, align->width, cur->output.buf);
444         strbuf_swap(&cur->output, &s);
445         strbuf_release(&s);
446 }
447
448 static void align_atom_handler(struct atom_value *atomv, struct ref_formatting_state *state)
449 {
450         struct ref_formatting_stack *new;
451
452         push_stack_element(&state->stack);
453         new = state->stack;
454         new->at_end = end_align_handler;
455         new->at_end_data = &atomv->atom->u.align;
456 }
457
458 static void if_then_else_handler(struct ref_formatting_stack **stack)
459 {
460         struct ref_formatting_stack *cur = *stack;
461         struct ref_formatting_stack *prev = cur->prev;
462         struct if_then_else *if_then_else = (struct if_then_else *)cur->at_end_data;
463
464         if (!if_then_else->then_atom_seen)
465                 die(_("format: %%(if) atom used without a %%(then) atom"));
466
467         if (if_then_else->else_atom_seen) {
468                 /*
469                  * There is an %(else) atom: we need to drop one state from the
470                  * stack, either the %(else) branch if the condition is satisfied, or
471                  * the %(then) branch if it isn't.
472                  */
473                 if (if_then_else->condition_satisfied) {
474                         strbuf_reset(&cur->output);
475                         pop_stack_element(&cur);
476                 } else {
477                         strbuf_swap(&cur->output, &prev->output);
478                         strbuf_reset(&cur->output);
479                         pop_stack_element(&cur);
480                 }
481         } else if (!if_then_else->condition_satisfied) {
482                 /*
483                  * No %(else) atom: just drop the %(then) branch if the
484                  * condition is not satisfied.
485                  */
486                 strbuf_reset(&cur->output);
487         }
488
489         *stack = cur;
490         free(if_then_else);
491 }
492
493 static void if_atom_handler(struct atom_value *atomv, struct ref_formatting_state *state)
494 {
495         struct ref_formatting_stack *new;
496         struct if_then_else *if_then_else = xcalloc(sizeof(struct if_then_else), 1);
497
498         if_then_else->str = atomv->atom->u.if_then_else.str;
499         if_then_else->cmp_status = atomv->atom->u.if_then_else.cmp_status;
500
501         push_stack_element(&state->stack);
502         new = state->stack;
503         new->at_end = if_then_else_handler;
504         new->at_end_data = if_then_else;
505 }
506
507 static int is_empty(const char *s)
508 {
509         while (*s != '\0') {
510                 if (!isspace(*s))
511                         return 0;
512                 s++;
513         }
514         return 1;
515 }
516
517 static void then_atom_handler(struct atom_value *atomv, struct ref_formatting_state *state)
518 {
519         struct ref_formatting_stack *cur = state->stack;
520         struct if_then_else *if_then_else = NULL;
521
522         if (cur->at_end == if_then_else_handler)
523                 if_then_else = (struct if_then_else *)cur->at_end_data;
524         if (!if_then_else)
525                 die(_("format: %%(then) atom used without an %%(if) atom"));
526         if (if_then_else->then_atom_seen)
527                 die(_("format: %%(then) atom used more than once"));
528         if (if_then_else->else_atom_seen)
529                 die(_("format: %%(then) atom used after %%(else)"));
530         if_then_else->then_atom_seen = 1;
531         /*
532          * If the 'equals' or 'notequals' attribute is used then
533          * perform the required comparison. If not, only non-empty
534          * strings satisfy the 'if' condition.
535          */
536         if (if_then_else->cmp_status == COMPARE_EQUAL) {
537                 if (!strcmp(if_then_else->str, cur->output.buf))
538                         if_then_else->condition_satisfied = 1;
539         } else if (if_then_else->cmp_status == COMPARE_UNEQUAL) {
540                 if (strcmp(if_then_else->str, cur->output.buf))
541                         if_then_else->condition_satisfied = 1;
542         } else if (cur->output.len && !is_empty(cur->output.buf))
543                 if_then_else->condition_satisfied = 1;
544         strbuf_reset(&cur->output);
545 }
546
547 static void else_atom_handler(struct atom_value *atomv, struct ref_formatting_state *state)
548 {
549         struct ref_formatting_stack *prev = state->stack;
550         struct if_then_else *if_then_else = NULL;
551
552         if (prev->at_end == if_then_else_handler)
553                 if_then_else = (struct if_then_else *)prev->at_end_data;
554         if (!if_then_else)
555                 die(_("format: %%(else) atom used without an %%(if) atom"));
556         if (!if_then_else->then_atom_seen)
557                 die(_("format: %%(else) atom used without a %%(then) atom"));
558         if (if_then_else->else_atom_seen)
559                 die(_("format: %%(else) atom used more than once"));
560         if_then_else->else_atom_seen = 1;
561         push_stack_element(&state->stack);
562         state->stack->at_end_data = prev->at_end_data;
563         state->stack->at_end = prev->at_end;
564 }
565
566 static void end_atom_handler(struct atom_value *atomv, struct ref_formatting_state *state)
567 {
568         struct ref_formatting_stack *current = state->stack;
569         struct strbuf s = STRBUF_INIT;
570
571         if (!current->at_end)
572                 die(_("format: %%(end) atom used without corresponding atom"));
573         current->at_end(&state->stack);
574
575         /*  Stack may have been popped within at_end(), hence reset the current pointer */
576         current = state->stack;
577
578         /*
579          * Perform quote formatting when the stack element is that of
580          * a supporting atom. If nested then perform quote formatting
581          * only on the topmost supporting atom.
582          */
583         if (!current->prev->prev) {
584                 quote_formatting(&s, current->output.buf, state->quote_style);
585                 strbuf_swap(&current->output, &s);
586         }
587         strbuf_release(&s);
588         pop_stack_element(&state->stack);
589 }
590
591 /*
592  * In a format string, find the next occurrence of %(atom).
593  */
594 static const char *find_next(const char *cp)
595 {
596         while (*cp) {
597                 if (*cp == '%') {
598                         /*
599                          * %( is the start of an atom;
600                          * %% is a quoted per-cent.
601                          */
602                         if (cp[1] == '(')
603                                 return cp;
604                         else if (cp[1] == '%')
605                                 cp++; /* skip over two % */
606                         /* otherwise this is a singleton, literal % */
607                 }
608                 cp++;
609         }
610         return NULL;
611 }
612
613 /*
614  * Make sure the format string is well formed, and parse out
615  * the used atoms.
616  */
617 int verify_ref_format(const char *format)
618 {
619         const char *cp, *sp;
620
621         need_color_reset_at_eol = 0;
622         for (cp = format; *cp && (sp = find_next(cp)); ) {
623                 const char *color, *ep = strchr(sp, ')');
624                 int at;
625
626                 if (!ep)
627                         return error(_("malformed format string %s"), sp);
628                 /* sp points at "%(" and ep points at the closing ")" */
629                 at = parse_ref_filter_atom(sp + 2, ep);
630                 cp = ep + 1;
631
632                 if (skip_prefix(used_atom[at].name, "color:", &color))
633                         need_color_reset_at_eol = !!strcmp(color, "reset");
634         }
635         return 0;
636 }
637
638 /*
639  * Given an object name, read the object data and size, and return a
640  * "struct object".  If the object data we are returning is also borrowed
641  * by the "struct object" representation, set *eaten as well---it is a
642  * signal from parse_object_buffer to us not to free the buffer.
643  */
644 static void *get_obj(const unsigned char *sha1, struct object **obj, unsigned long *sz, int *eaten)
645 {
646         enum object_type type;
647         void *buf = read_sha1_file(sha1, &type, sz);
648
649         if (buf)
650                 *obj = parse_object_buffer(sha1, type, *sz, buf, eaten);
651         else
652                 *obj = NULL;
653         return buf;
654 }
655
656 static int grab_objectname(const char *name, const unsigned char *sha1,
657                            struct atom_value *v, struct used_atom *atom)
658 {
659         if (starts_with(name, "objectname")) {
660                 if (atom->u.objectname.option == O_SHORT) {
661                         v->s = xstrdup(find_unique_abbrev(sha1, DEFAULT_ABBREV));
662                         return 1;
663                 } else if (atom->u.objectname.option == O_FULL) {
664                         v->s = xstrdup(sha1_to_hex(sha1));
665                         return 1;
666                 } else if (atom->u.objectname.option == O_LENGTH) {
667                         v->s = xstrdup(find_unique_abbrev(sha1, atom->u.objectname.length));
668                         return 1;
669                 } else
670                         die("BUG: unknown %%(objectname) option");
671         }
672         return 0;
673 }
674
675 /* See grab_values */
676 static void grab_common_values(struct atom_value *val, int deref, struct object *obj, void *buf, unsigned long sz)
677 {
678         int i;
679
680         for (i = 0; i < used_atom_cnt; i++) {
681                 const char *name = used_atom[i].name;
682                 struct atom_value *v = &val[i];
683                 if (!!deref != (*name == '*'))
684                         continue;
685                 if (deref)
686                         name++;
687                 if (!strcmp(name, "objecttype"))
688                         v->s = typename(obj->type);
689                 else if (!strcmp(name, "objectsize")) {
690                         v->ul = sz;
691                         v->s = xstrfmt("%lu", sz);
692                 }
693                 else if (deref)
694                         grab_objectname(name, obj->oid.hash, v, &used_atom[i]);
695         }
696 }
697
698 /* See grab_values */
699 static void grab_tag_values(struct atom_value *val, int deref, struct object *obj, void *buf, unsigned long sz)
700 {
701         int i;
702         struct tag *tag = (struct tag *) obj;
703
704         for (i = 0; i < used_atom_cnt; i++) {
705                 const char *name = used_atom[i].name;
706                 struct atom_value *v = &val[i];
707                 if (!!deref != (*name == '*'))
708                         continue;
709                 if (deref)
710                         name++;
711                 if (!strcmp(name, "tag"))
712                         v->s = tag->tag;
713                 else if (!strcmp(name, "type") && tag->tagged)
714                         v->s = typename(tag->tagged->type);
715                 else if (!strcmp(name, "object") && tag->tagged)
716                         v->s = xstrdup(oid_to_hex(&tag->tagged->oid));
717         }
718 }
719
720 /* See grab_values */
721 static void grab_commit_values(struct atom_value *val, int deref, struct object *obj, void *buf, unsigned long sz)
722 {
723         int i;
724         struct commit *commit = (struct commit *) obj;
725
726         for (i = 0; i < used_atom_cnt; i++) {
727                 const char *name = used_atom[i].name;
728                 struct atom_value *v = &val[i];
729                 if (!!deref != (*name == '*'))
730                         continue;
731                 if (deref)
732                         name++;
733                 if (!strcmp(name, "tree")) {
734                         v->s = xstrdup(oid_to_hex(&commit->tree->object.oid));
735                 }
736                 else if (!strcmp(name, "numparent")) {
737                         v->ul = commit_list_count(commit->parents);
738                         v->s = xstrfmt("%lu", v->ul);
739                 }
740                 else if (!strcmp(name, "parent")) {
741                         struct commit_list *parents;
742                         struct strbuf s = STRBUF_INIT;
743                         for (parents = commit->parents; parents; parents = parents->next) {
744                                 struct commit *parent = parents->item;
745                                 if (parents != commit->parents)
746                                         strbuf_addch(&s, ' ');
747                                 strbuf_addstr(&s, oid_to_hex(&parent->object.oid));
748                         }
749                         v->s = strbuf_detach(&s, NULL);
750                 }
751         }
752 }
753
754 static const char *find_wholine(const char *who, int wholen, const char *buf, unsigned long sz)
755 {
756         const char *eol;
757         while (*buf) {
758                 if (!strncmp(buf, who, wholen) &&
759                     buf[wholen] == ' ')
760                         return buf + wholen + 1;
761                 eol = strchr(buf, '\n');
762                 if (!eol)
763                         return "";
764                 eol++;
765                 if (*eol == '\n')
766                         return ""; /* end of header */
767                 buf = eol;
768         }
769         return "";
770 }
771
772 static const char *copy_line(const char *buf)
773 {
774         const char *eol = strchrnul(buf, '\n');
775         return xmemdupz(buf, eol - buf);
776 }
777
778 static const char *copy_name(const char *buf)
779 {
780         const char *cp;
781         for (cp = buf; *cp && *cp != '\n'; cp++) {
782                 if (!strncmp(cp, " <", 2))
783                         return xmemdupz(buf, cp - buf);
784         }
785         return "";
786 }
787
788 static const char *copy_email(const char *buf)
789 {
790         const char *email = strchr(buf, '<');
791         const char *eoemail;
792         if (!email)
793                 return "";
794         eoemail = strchr(email, '>');
795         if (!eoemail)
796                 return "";
797         return xmemdupz(email, eoemail + 1 - email);
798 }
799
800 static char *copy_subject(const char *buf, unsigned long len)
801 {
802         char *r = xmemdupz(buf, len);
803         int i;
804
805         for (i = 0; i < len; i++)
806                 if (r[i] == '\n')
807                         r[i] = ' ';
808
809         return r;
810 }
811
812 static void grab_date(const char *buf, struct atom_value *v, const char *atomname)
813 {
814         const char *eoemail = strstr(buf, "> ");
815         char *zone;
816         unsigned long timestamp;
817         long tz;
818         struct date_mode date_mode = { DATE_NORMAL };
819         const char *formatp;
820
821         /*
822          * We got here because atomname ends in "date" or "date<something>";
823          * it's not possible that <something> is not ":<format>" because
824          * parse_ref_filter_atom() wouldn't have allowed it, so we can assume that no
825          * ":" means no format is specified, and use the default.
826          */
827         formatp = strchr(atomname, ':');
828         if (formatp != NULL) {
829                 formatp++;
830                 parse_date_format(formatp, &date_mode);
831         }
832
833         if (!eoemail)
834                 goto bad;
835         timestamp = strtoul(eoemail + 2, &zone, 10);
836         if (timestamp == ULONG_MAX)
837                 goto bad;
838         tz = strtol(zone, NULL, 10);
839         if ((tz == LONG_MIN || tz == LONG_MAX) && errno == ERANGE)
840                 goto bad;
841         v->s = xstrdup(show_date(timestamp, tz, &date_mode));
842         v->ul = timestamp;
843         return;
844  bad:
845         v->s = "";
846         v->ul = 0;
847 }
848
849 /* See grab_values */
850 static void grab_person(const char *who, struct atom_value *val, int deref, struct object *obj, void *buf, unsigned long sz)
851 {
852         int i;
853         int wholen = strlen(who);
854         const char *wholine = NULL;
855
856         for (i = 0; i < used_atom_cnt; i++) {
857                 const char *name = used_atom[i].name;
858                 struct atom_value *v = &val[i];
859                 if (!!deref != (*name == '*'))
860                         continue;
861                 if (deref)
862                         name++;
863                 if (strncmp(who, name, wholen))
864                         continue;
865                 if (name[wholen] != 0 &&
866                     strcmp(name + wholen, "name") &&
867                     strcmp(name + wholen, "email") &&
868                     !starts_with(name + wholen, "date"))
869                         continue;
870                 if (!wholine)
871                         wholine = find_wholine(who, wholen, buf, sz);
872                 if (!wholine)
873                         return; /* no point looking for it */
874                 if (name[wholen] == 0)
875                         v->s = copy_line(wholine);
876                 else if (!strcmp(name + wholen, "name"))
877                         v->s = copy_name(wholine);
878                 else if (!strcmp(name + wholen, "email"))
879                         v->s = copy_email(wholine);
880                 else if (starts_with(name + wholen, "date"))
881                         grab_date(wholine, v, name);
882         }
883
884         /*
885          * For a tag or a commit object, if "creator" or "creatordate" is
886          * requested, do something special.
887          */
888         if (strcmp(who, "tagger") && strcmp(who, "committer"))
889                 return; /* "author" for commit object is not wanted */
890         if (!wholine)
891                 wholine = find_wholine(who, wholen, buf, sz);
892         if (!wholine)
893                 return;
894         for (i = 0; i < used_atom_cnt; i++) {
895                 const char *name = used_atom[i].name;
896                 struct atom_value *v = &val[i];
897                 if (!!deref != (*name == '*'))
898                         continue;
899                 if (deref)
900                         name++;
901
902                 if (starts_with(name, "creatordate"))
903                         grab_date(wholine, v, name);
904                 else if (!strcmp(name, "creator"))
905                         v->s = copy_line(wholine);
906         }
907 }
908
909 static void find_subpos(const char *buf, unsigned long sz,
910                         const char **sub, unsigned long *sublen,
911                         const char **body, unsigned long *bodylen,
912                         unsigned long *nonsiglen,
913                         const char **sig, unsigned long *siglen)
914 {
915         const char *eol;
916         /* skip past header until we hit empty line */
917         while (*buf && *buf != '\n') {
918                 eol = strchrnul(buf, '\n');
919                 if (*eol)
920                         eol++;
921                 buf = eol;
922         }
923         /* skip any empty lines */
924         while (*buf == '\n')
925                 buf++;
926
927         /* parse signature first; we might not even have a subject line */
928         *sig = buf + parse_signature(buf, strlen(buf));
929         *siglen = strlen(*sig);
930
931         /* subject is first non-empty line */
932         *sub = buf;
933         /* subject goes to first empty line */
934         while (buf < *sig && *buf && *buf != '\n') {
935                 eol = strchrnul(buf, '\n');
936                 if (*eol)
937                         eol++;
938                 buf = eol;
939         }
940         *sublen = buf - *sub;
941         /* drop trailing newline, if present */
942         if (*sublen && (*sub)[*sublen - 1] == '\n')
943                 *sublen -= 1;
944
945         /* skip any empty lines */
946         while (*buf == '\n')
947                 buf++;
948         *body = buf;
949         *bodylen = strlen(buf);
950         *nonsiglen = *sig - buf;
951 }
952
953 /*
954  * If 'lines' is greater than 0, append that many lines from the given
955  * 'buf' of length 'size' to the given strbuf.
956  */
957 static void append_lines(struct strbuf *out, const char *buf, unsigned long size, int lines)
958 {
959         int i;
960         const char *sp, *eol;
961         size_t len;
962
963         sp = buf;
964
965         for (i = 0; i < lines && sp < buf + size; i++) {
966                 if (i)
967                         strbuf_addstr(out, "\n    ");
968                 eol = memchr(sp, '\n', size - (sp - buf));
969                 len = eol ? eol - sp : size - (sp - buf);
970                 strbuf_add(out, sp, len);
971                 if (!eol)
972                         break;
973                 sp = eol + 1;
974         }
975 }
976
977 /* See grab_values */
978 static void grab_sub_body_contents(struct atom_value *val, int deref, struct object *obj, void *buf, unsigned long sz)
979 {
980         int i;
981         const char *subpos = NULL, *bodypos = NULL, *sigpos = NULL;
982         unsigned long sublen = 0, bodylen = 0, nonsiglen = 0, siglen = 0;
983
984         for (i = 0; i < used_atom_cnt; i++) {
985                 struct used_atom *atom = &used_atom[i];
986                 const char *name = atom->name;
987                 struct atom_value *v = &val[i];
988                 if (!!deref != (*name == '*'))
989                         continue;
990                 if (deref)
991                         name++;
992                 if (strcmp(name, "subject") &&
993                     strcmp(name, "body") &&
994                     strcmp(name, "trailers") &&
995                     !starts_with(name, "contents"))
996                         continue;
997                 if (!subpos)
998                         find_subpos(buf, sz,
999                                     &subpos, &sublen,
1000                                     &bodypos, &bodylen, &nonsiglen,
1001                                     &sigpos, &siglen);
1002
1003                 if (atom->u.contents.option == C_SUB)
1004                         v->s = copy_subject(subpos, sublen);
1005                 else if (atom->u.contents.option == C_BODY_DEP)
1006                         v->s = xmemdupz(bodypos, bodylen);
1007                 else if (atom->u.contents.option == C_BODY)
1008                         v->s = xmemdupz(bodypos, nonsiglen);
1009                 else if (atom->u.contents.option == C_SIG)
1010                         v->s = xmemdupz(sigpos, siglen);
1011                 else if (atom->u.contents.option == C_LINES) {
1012                         struct strbuf s = STRBUF_INIT;
1013                         const char *contents_end = bodylen + bodypos - siglen;
1014
1015                         /*  Size is the length of the message after removing the signature */
1016                         append_lines(&s, subpos, contents_end - subpos, atom->u.contents.nlines);
1017                         v->s = strbuf_detach(&s, NULL);
1018                 } else if (atom->u.contents.option == C_TRAILERS) {
1019                         struct trailer_info info;
1020
1021                         /* Search for trailer info */
1022                         trailer_info_get(&info, subpos);
1023                         v->s = xmemdupz(info.trailer_start,
1024                                         info.trailer_end - info.trailer_start);
1025                         trailer_info_release(&info);
1026                 } else if (atom->u.contents.option == C_BARE)
1027                         v->s = xstrdup(subpos);
1028         }
1029 }
1030
1031 /*
1032  * We want to have empty print-string for field requests
1033  * that do not apply (e.g. "authordate" for a tag object)
1034  */
1035 static void fill_missing_values(struct atom_value *val)
1036 {
1037         int i;
1038         for (i = 0; i < used_atom_cnt; i++) {
1039                 struct atom_value *v = &val[i];
1040                 if (v->s == NULL)
1041                         v->s = "";
1042         }
1043 }
1044
1045 /*
1046  * val is a list of atom_value to hold returned values.  Extract
1047  * the values for atoms in used_atom array out of (obj, buf, sz).
1048  * when deref is false, (obj, buf, sz) is the object that is
1049  * pointed at by the ref itself; otherwise it is the object the
1050  * ref (which is a tag) refers to.
1051  */
1052 static void grab_values(struct atom_value *val, int deref, struct object *obj, void *buf, unsigned long sz)
1053 {
1054         grab_common_values(val, deref, obj, buf, sz);
1055         switch (obj->type) {
1056         case OBJ_TAG:
1057                 grab_tag_values(val, deref, obj, buf, sz);
1058                 grab_sub_body_contents(val, deref, obj, buf, sz);
1059                 grab_person("tagger", val, deref, obj, buf, sz);
1060                 break;
1061         case OBJ_COMMIT:
1062                 grab_commit_values(val, deref, obj, buf, sz);
1063                 grab_sub_body_contents(val, deref, obj, buf, sz);
1064                 grab_person("author", val, deref, obj, buf, sz);
1065                 grab_person("committer", val, deref, obj, buf, sz);
1066                 break;
1067         case OBJ_TREE:
1068                 /* grab_tree_values(val, deref, obj, buf, sz); */
1069                 break;
1070         case OBJ_BLOB:
1071                 /* grab_blob_values(val, deref, obj, buf, sz); */
1072                 break;
1073         default:
1074                 die("Eh?  Object of type %d?", obj->type);
1075         }
1076 }
1077
1078 static inline char *copy_advance(char *dst, const char *src)
1079 {
1080         while (*src)
1081                 *dst++ = *src++;
1082         return dst;
1083 }
1084
1085 static const char *strip_ref_components(const char *refname, const char *nr_arg)
1086 {
1087         char *end;
1088         long nr = strtol(nr_arg, &end, 10);
1089         long remaining = nr;
1090         const char *start = refname;
1091
1092         if (nr < 1 || *end != '\0')
1093                 die(_(":strip= requires a positive integer argument"));
1094
1095         while (remaining) {
1096                 switch (*start++) {
1097                 case '\0':
1098                         die(_("ref '%s' does not have %ld components to :strip"),
1099                             refname, nr);
1100                 case '/':
1101                         remaining--;
1102                         break;
1103                 }
1104         }
1105         return start;
1106 }
1107
1108 static void fill_remote_ref_details(struct used_atom *atom, const char *refname,
1109                                     struct branch *branch, const char **s)
1110 {
1111         int num_ours, num_theirs;
1112         if (atom->u.remote_ref.option == RR_SHORTEN)
1113                 *s = shorten_unambiguous_ref(refname, warn_ambiguous_refs);
1114         else if (atom->u.remote_ref.option == RR_TRACK) {
1115                 if (stat_tracking_info(branch, &num_ours,
1116                                        &num_theirs, NULL)) {
1117                         *s = xstrdup("gone");
1118                 } else if (!num_ours && !num_theirs)
1119                         *s = "";
1120                 else if (!num_ours)
1121                         *s = xstrfmt("behind %d", num_theirs);
1122                 else if (!num_theirs)
1123                         *s = xstrfmt("ahead %d", num_ours);
1124                 else
1125                         *s = xstrfmt("ahead %d, behind %d",
1126                                      num_ours, num_theirs);
1127                 if (!atom->u.remote_ref.nobracket && *s[0]) {
1128                         const char *to_free = *s;
1129                         *s = xstrfmt("[%s]", *s);
1130                         free((void *)to_free);
1131                 }
1132         } else if (atom->u.remote_ref.option == RR_TRACKSHORT) {
1133                 if (stat_tracking_info(branch, &num_ours,
1134                                        &num_theirs, NULL))
1135                         return;
1136
1137                 if (!num_ours && !num_theirs)
1138                         *s = "=";
1139                 else if (!num_ours)
1140                         *s = "<";
1141                 else if (!num_theirs)
1142                         *s = ">";
1143                 else
1144                         *s = "<>";
1145         } else /* RR_NORMAL */
1146                 *s = refname;
1147 }
1148
1149 char *get_head_description(void)
1150 {
1151         struct strbuf desc = STRBUF_INIT;
1152         struct wt_status_state state;
1153         memset(&state, 0, sizeof(state));
1154         wt_status_get_state(&state, 1);
1155         if (state.rebase_in_progress ||
1156             state.rebase_interactive_in_progress)
1157                 strbuf_addf(&desc, _("(no branch, rebasing %s)"),
1158                             state.branch);
1159         else if (state.bisect_in_progress)
1160                 strbuf_addf(&desc, _("(no branch, bisect started on %s)"),
1161                             state.branch);
1162         else if (state.detached_from) {
1163                 /* TRANSLATORS: make sure these match _("HEAD detached at ")
1164                    and _("HEAD detached from ") in wt-status.c */
1165                 if (state.detached_at)
1166                         strbuf_addf(&desc, _("(HEAD detached at %s)"),
1167                                 state.detached_from);
1168                 else
1169                         strbuf_addf(&desc, _("(HEAD detached from %s)"),
1170                                 state.detached_from);
1171         }
1172         else
1173                 strbuf_addstr(&desc, _("(no branch)"));
1174         free(state.branch);
1175         free(state.onto);
1176         free(state.detached_from);
1177         return strbuf_detach(&desc, NULL);
1178 }
1179
1180 /*
1181  * Parse the object referred by ref, and grab needed value.
1182  */
1183 static void populate_value(struct ref_array_item *ref)
1184 {
1185         void *buf;
1186         struct object *obj;
1187         int eaten, i;
1188         unsigned long size;
1189         const unsigned char *tagged;
1190
1191         ref->value = xcalloc(used_atom_cnt, sizeof(struct atom_value));
1192
1193         if (need_symref && (ref->flag & REF_ISSYMREF) && !ref->symref) {
1194                 unsigned char unused1[20];
1195                 ref->symref = resolve_refdup(ref->refname, RESOLVE_REF_READING,
1196                                              unused1, NULL);
1197                 if (!ref->symref)
1198                         ref->symref = "";
1199         }
1200
1201         /* Fill in specials first */
1202         for (i = 0; i < used_atom_cnt; i++) {
1203                 struct used_atom *atom = &used_atom[i];
1204                 const char *name = used_atom[i].name;
1205                 struct atom_value *v = &ref->value[i];
1206                 int deref = 0;
1207                 const char *refname;
1208                 const char *formatp;
1209                 struct branch *branch = NULL;
1210
1211                 v->handler = append_atom;
1212                 v->atom = atom;
1213
1214                 if (*name == '*') {
1215                         deref = 1;
1216                         name++;
1217                 }
1218
1219                 if (starts_with(name, "refname")) {
1220                         refname = ref->refname;
1221                         if (ref->kind & FILTER_REFS_DETACHED_HEAD)
1222                                 refname = get_head_description();
1223                 } else if (starts_with(name, "symref"))
1224                         refname = ref->symref ? ref->symref : "";
1225                 else if (starts_with(name, "upstream")) {
1226                         const char *branch_name;
1227                         /* only local branches may have an upstream */
1228                         if (!skip_prefix(ref->refname, "refs/heads/",
1229                                          &branch_name))
1230                                 continue;
1231                         branch = branch_get(branch_name);
1232
1233                         refname = branch_get_upstream(branch, NULL);
1234                         if (refname)
1235                                 fill_remote_ref_details(atom, refname, branch, &v->s);
1236                         continue;
1237                 } else if (starts_with(name, "push")) {
1238                         const char *branch_name;
1239                         if (!skip_prefix(ref->refname, "refs/heads/",
1240                                          &branch_name))
1241                                 continue;
1242                         branch = branch_get(branch_name);
1243
1244                         refname = branch_get_push(branch, NULL);
1245                         if (!refname)
1246                                 continue;
1247                         fill_remote_ref_details(atom, refname, branch, &v->s);
1248                         continue;
1249                 } else if (starts_with(name, "color:")) {
1250                         v->s = atom->u.color;
1251                         continue;
1252                 } else if (!strcmp(name, "flag")) {
1253                         char buf[256], *cp = buf;
1254                         if (ref->flag & REF_ISSYMREF)
1255                                 cp = copy_advance(cp, ",symref");
1256                         if (ref->flag & REF_ISPACKED)
1257                                 cp = copy_advance(cp, ",packed");
1258                         if (cp == buf)
1259                                 v->s = "";
1260                         else {
1261                                 *cp = '\0';
1262                                 v->s = xstrdup(buf + 1);
1263                         }
1264                         continue;
1265                 } else if (!deref && grab_objectname(name, ref->objectname, v, atom)) {
1266                         continue;
1267                 } else if (!strcmp(name, "HEAD")) {
1268                         const char *head;
1269                         unsigned char sha1[20];
1270
1271                         head = resolve_ref_unsafe("HEAD", RESOLVE_REF_READING,
1272                                                   sha1, NULL);
1273                         if (head && !strcmp(ref->refname, head))
1274                                 v->s = "*";
1275                         else
1276                                 v->s = " ";
1277                         continue;
1278                 } else if (starts_with(name, "align")) {
1279                         v->handler = align_atom_handler;
1280                         continue;
1281                 } else if (!strcmp(name, "end")) {
1282                         v->handler = end_atom_handler;
1283                         continue;
1284                 } else if (starts_with(name, "if")) {
1285                         const char *s;
1286
1287                         if (skip_prefix(name, "if:", &s))
1288                                 v->s = xstrdup(s);
1289                         v->handler = if_atom_handler;
1290                         continue;
1291                 } else if (!strcmp(name, "then")) {
1292                         v->handler = then_atom_handler;
1293                         continue;
1294                 } else if (!strcmp(name, "else")) {
1295                         v->handler = else_atom_handler;
1296                         continue;
1297                 } else
1298                         continue;
1299
1300                 formatp = strchr(name, ':');
1301                 if (formatp) {
1302                         const char *arg;
1303
1304                         formatp++;
1305                         if (!strcmp(formatp, "short"))
1306                                 refname = shorten_unambiguous_ref(refname,
1307                                                       warn_ambiguous_refs);
1308                         else if (skip_prefix(formatp, "strip=", &arg))
1309                                 refname = strip_ref_components(refname, arg);
1310                         else
1311                                 die(_("unknown %.*s format %s"),
1312                                     (int)(formatp - name), name, formatp);
1313                 }
1314
1315                 if (!deref)
1316                         v->s = refname;
1317                 else
1318                         v->s = xstrfmt("%s^{}", refname);
1319         }
1320
1321         for (i = 0; i < used_atom_cnt; i++) {
1322                 struct atom_value *v = &ref->value[i];
1323                 if (v->s == NULL)
1324                         goto need_obj;
1325         }
1326         return;
1327
1328  need_obj:
1329         buf = get_obj(ref->objectname, &obj, &size, &eaten);
1330         if (!buf)
1331                 die(_("missing object %s for %s"),
1332                     sha1_to_hex(ref->objectname), ref->refname);
1333         if (!obj)
1334                 die(_("parse_object_buffer failed on %s for %s"),
1335                     sha1_to_hex(ref->objectname), ref->refname);
1336
1337         grab_values(ref->value, 0, obj, buf, size);
1338         if (!eaten)
1339                 free(buf);
1340
1341         /*
1342          * If there is no atom that wants to know about tagged
1343          * object, we are done.
1344          */
1345         if (!need_tagged || (obj->type != OBJ_TAG))
1346                 return;
1347
1348         /*
1349          * If it is a tag object, see if we use a value that derefs
1350          * the object, and if we do grab the object it refers to.
1351          */
1352         tagged = ((struct tag *)obj)->tagged->oid.hash;
1353
1354         /*
1355          * NEEDSWORK: This derefs tag only once, which
1356          * is good to deal with chains of trust, but
1357          * is not consistent with what deref_tag() does
1358          * which peels the onion to the core.
1359          */
1360         buf = get_obj(tagged, &obj, &size, &eaten);
1361         if (!buf)
1362                 die(_("missing object %s for %s"),
1363                     sha1_to_hex(tagged), ref->refname);
1364         if (!obj)
1365                 die(_("parse_object_buffer failed on %s for %s"),
1366                     sha1_to_hex(tagged), ref->refname);
1367         grab_values(ref->value, 1, obj, buf, size);
1368         if (!eaten)
1369                 free(buf);
1370 }
1371
1372 /*
1373  * Given a ref, return the value for the atom.  This lazily gets value
1374  * out of the object by calling populate value.
1375  */
1376 static void get_ref_atom_value(struct ref_array_item *ref, int atom, struct atom_value **v)
1377 {
1378         if (!ref->value) {
1379                 populate_value(ref);
1380                 fill_missing_values(ref->value);
1381         }
1382         *v = &ref->value[atom];
1383 }
1384
1385 enum contains_result {
1386         CONTAINS_UNKNOWN = -1,
1387         CONTAINS_NO = 0,
1388         CONTAINS_YES = 1
1389 };
1390
1391 /*
1392  * Mimicking the real stack, this stack lives on the heap, avoiding stack
1393  * overflows.
1394  *
1395  * At each recursion step, the stack items points to the commits whose
1396  * ancestors are to be inspected.
1397  */
1398 struct contains_stack {
1399         int nr, alloc;
1400         struct contains_stack_entry {
1401                 struct commit *commit;
1402                 struct commit_list *parents;
1403         } *contains_stack;
1404 };
1405
1406 static int in_commit_list(const struct commit_list *want, struct commit *c)
1407 {
1408         for (; want; want = want->next)
1409                 if (!oidcmp(&want->item->object.oid, &c->object.oid))
1410                         return 1;
1411         return 0;
1412 }
1413
1414 /*
1415  * Test whether the candidate or one of its parents is contained in the list.
1416  * Do not recurse to find out, though, but return -1 if inconclusive.
1417  */
1418 static enum contains_result contains_test(struct commit *candidate,
1419                             const struct commit_list *want)
1420 {
1421         /* was it previously marked as containing a want commit? */
1422         if (candidate->object.flags & TMP_MARK)
1423                 return 1;
1424         /* or marked as not possibly containing a want commit? */
1425         if (candidate->object.flags & UNINTERESTING)
1426                 return 0;
1427         /* or are we it? */
1428         if (in_commit_list(want, candidate)) {
1429                 candidate->object.flags |= TMP_MARK;
1430                 return 1;
1431         }
1432
1433         if (parse_commit(candidate) < 0)
1434                 return 0;
1435
1436         return -1;
1437 }
1438
1439 static void push_to_contains_stack(struct commit *candidate, struct contains_stack *contains_stack)
1440 {
1441         ALLOC_GROW(contains_stack->contains_stack, contains_stack->nr + 1, contains_stack->alloc);
1442         contains_stack->contains_stack[contains_stack->nr].commit = candidate;
1443         contains_stack->contains_stack[contains_stack->nr++].parents = candidate->parents;
1444 }
1445
1446 static enum contains_result contains_tag_algo(struct commit *candidate,
1447                 const struct commit_list *want)
1448 {
1449         struct contains_stack contains_stack = { 0, 0, NULL };
1450         int result = contains_test(candidate, want);
1451
1452         if (result != CONTAINS_UNKNOWN)
1453                 return result;
1454
1455         push_to_contains_stack(candidate, &contains_stack);
1456         while (contains_stack.nr) {
1457                 struct contains_stack_entry *entry = &contains_stack.contains_stack[contains_stack.nr - 1];
1458                 struct commit *commit = entry->commit;
1459                 struct commit_list *parents = entry->parents;
1460
1461                 if (!parents) {
1462                         commit->object.flags |= UNINTERESTING;
1463                         contains_stack.nr--;
1464                 }
1465                 /*
1466                  * If we just popped the stack, parents->item has been marked,
1467                  * therefore contains_test will return a meaningful 0 or 1.
1468                  */
1469                 else switch (contains_test(parents->item, want)) {
1470                 case CONTAINS_YES:
1471                         commit->object.flags |= TMP_MARK;
1472                         contains_stack.nr--;
1473                         break;
1474                 case CONTAINS_NO:
1475                         entry->parents = parents->next;
1476                         break;
1477                 case CONTAINS_UNKNOWN:
1478                         push_to_contains_stack(parents->item, &contains_stack);
1479                         break;
1480                 }
1481         }
1482         free(contains_stack.contains_stack);
1483         return contains_test(candidate, want);
1484 }
1485
1486 static int commit_contains(struct ref_filter *filter, struct commit *commit)
1487 {
1488         if (filter->with_commit_tag_algo)
1489                 return contains_tag_algo(commit, filter->with_commit);
1490         return is_descendant_of(commit, filter->with_commit);
1491 }
1492
1493 /*
1494  * Return 1 if the refname matches one of the patterns, otherwise 0.
1495  * A pattern can be a literal prefix (e.g. a refname "refs/heads/master"
1496  * matches a pattern "refs/heads/mas") or a wildcard (e.g. the same ref
1497  * matches "refs/heads/mas*", too).
1498  */
1499 static int match_pattern(const struct ref_filter *filter, const char *refname)
1500 {
1501         const char **patterns = filter->name_patterns;
1502         unsigned flags = 0;
1503
1504         if (filter->ignore_case)
1505                 flags |= WM_CASEFOLD;
1506
1507         /*
1508          * When no '--format' option is given we need to skip the prefix
1509          * for matching refs of tags and branches.
1510          */
1511         (void)(skip_prefix(refname, "refs/tags/", &refname) ||
1512                skip_prefix(refname, "refs/heads/", &refname) ||
1513                skip_prefix(refname, "refs/remotes/", &refname) ||
1514                skip_prefix(refname, "refs/", &refname));
1515
1516         for (; *patterns; patterns++) {
1517                 if (!wildmatch(*patterns, refname, flags, NULL))
1518                         return 1;
1519         }
1520         return 0;
1521 }
1522
1523 /*
1524  * Return 1 if the refname matches one of the patterns, otherwise 0.
1525  * A pattern can be path prefix (e.g. a refname "refs/heads/master"
1526  * matches a pattern "refs/heads/" but not "refs/heads/m") or a
1527  * wildcard (e.g. the same ref matches "refs/heads/m*", too).
1528  */
1529 static int match_name_as_path(const struct ref_filter *filter, const char *refname)
1530 {
1531         const char **pattern = filter->name_patterns;
1532         int namelen = strlen(refname);
1533         unsigned flags = WM_PATHNAME;
1534
1535         if (filter->ignore_case)
1536                 flags |= WM_CASEFOLD;
1537
1538         for (; *pattern; pattern++) {
1539                 const char *p = *pattern;
1540                 int plen = strlen(p);
1541
1542                 if ((plen <= namelen) &&
1543                     !strncmp(refname, p, plen) &&
1544                     (refname[plen] == '\0' ||
1545                      refname[plen] == '/' ||
1546                      p[plen-1] == '/'))
1547                         return 1;
1548                 if (!wildmatch(p, refname, WM_PATHNAME, NULL))
1549                         return 1;
1550         }
1551         return 0;
1552 }
1553
1554 /* Return 1 if the refname matches one of the patterns, otherwise 0. */
1555 static int filter_pattern_match(struct ref_filter *filter, const char *refname)
1556 {
1557         if (!*filter->name_patterns)
1558                 return 1; /* No pattern always matches */
1559         if (filter->match_as_path)
1560                 return match_name_as_path(filter, refname);
1561         return match_pattern(filter, refname);
1562 }
1563
1564 /*
1565  * Given a ref (sha1, refname), check if the ref belongs to the array
1566  * of sha1s. If the given ref is a tag, check if the given tag points
1567  * at one of the sha1s in the given sha1 array.
1568  * the given sha1_array.
1569  * NEEDSWORK:
1570  * 1. Only a single level of inderection is obtained, we might want to
1571  * change this to account for multiple levels (e.g. annotated tags
1572  * pointing to annotated tags pointing to a commit.)
1573  * 2. As the refs are cached we might know what refname peels to without
1574  * the need to parse the object via parse_object(). peel_ref() might be a
1575  * more efficient alternative to obtain the pointee.
1576  */
1577 static const unsigned char *match_points_at(struct sha1_array *points_at,
1578                                             const unsigned char *sha1,
1579                                             const char *refname)
1580 {
1581         const unsigned char *tagged_sha1 = NULL;
1582         struct object *obj;
1583
1584         if (sha1_array_lookup(points_at, sha1) >= 0)
1585                 return sha1;
1586         obj = parse_object(sha1);
1587         if (!obj)
1588                 die(_("malformed object at '%s'"), refname);
1589         if (obj->type == OBJ_TAG)
1590                 tagged_sha1 = ((struct tag *)obj)->tagged->oid.hash;
1591         if (tagged_sha1 && sha1_array_lookup(points_at, tagged_sha1) >= 0)
1592                 return tagged_sha1;
1593         return NULL;
1594 }
1595
1596 /* Allocate space for a new ref_array_item and copy the objectname and flag to it */
1597 static struct ref_array_item *new_ref_array_item(const char *refname,
1598                                                  const unsigned char *objectname,
1599                                                  int flag)
1600 {
1601         struct ref_array_item *ref;
1602         FLEX_ALLOC_STR(ref, refname, refname);
1603         hashcpy(ref->objectname, objectname);
1604         ref->flag = flag;
1605
1606         return ref;
1607 }
1608
1609 static int filter_ref_kind(struct ref_filter *filter, const char *refname)
1610 {
1611         unsigned int i;
1612
1613         static struct {
1614                 const char *prefix;
1615                 unsigned int kind;
1616         } ref_kind[] = {
1617                 { "refs/heads/" , FILTER_REFS_BRANCHES },
1618                 { "refs/remotes/" , FILTER_REFS_REMOTES },
1619                 { "refs/tags/", FILTER_REFS_TAGS}
1620         };
1621
1622         if (filter->kind == FILTER_REFS_BRANCHES ||
1623             filter->kind == FILTER_REFS_REMOTES ||
1624             filter->kind == FILTER_REFS_TAGS)
1625                 return filter->kind;
1626         else if (!strcmp(refname, "HEAD"))
1627                 return FILTER_REFS_DETACHED_HEAD;
1628
1629         for (i = 0; i < ARRAY_SIZE(ref_kind); i++) {
1630                 if (starts_with(refname, ref_kind[i].prefix))
1631                         return ref_kind[i].kind;
1632         }
1633
1634         return FILTER_REFS_OTHERS;
1635 }
1636
1637 /*
1638  * A call-back given to for_each_ref().  Filter refs and keep them for
1639  * later object processing.
1640  */
1641 static int ref_filter_handler(const char *refname, const struct object_id *oid, int flag, void *cb_data)
1642 {
1643         struct ref_filter_cbdata *ref_cbdata = cb_data;
1644         struct ref_filter *filter = ref_cbdata->filter;
1645         struct ref_array_item *ref;
1646         struct commit *commit = NULL;
1647         unsigned int kind;
1648
1649         if (flag & REF_BAD_NAME) {
1650                 warning(_("ignoring ref with broken name %s"), refname);
1651                 return 0;
1652         }
1653
1654         if (flag & REF_ISBROKEN) {
1655                 warning(_("ignoring broken ref %s"), refname);
1656                 return 0;
1657         }
1658
1659         /* Obtain the current ref kind from filter_ref_kind() and ignore unwanted refs. */
1660         kind = filter_ref_kind(filter, refname);
1661         if (!(kind & filter->kind))
1662                 return 0;
1663
1664         if (!filter_pattern_match(filter, refname))
1665                 return 0;
1666
1667         if (filter->points_at.nr && !match_points_at(&filter->points_at, oid->hash, refname))
1668                 return 0;
1669
1670         /*
1671          * A merge filter is applied on refs pointing to commits. Hence
1672          * obtain the commit using the 'oid' available and discard all
1673          * non-commits early. The actual filtering is done later.
1674          */
1675         if (filter->merge_commit || filter->with_commit || filter->verbose) {
1676                 commit = lookup_commit_reference_gently(oid->hash, 1);
1677                 if (!commit)
1678                         return 0;
1679                 /* We perform the filtering for the '--contains' option */
1680                 if (filter->with_commit &&
1681                     !commit_contains(filter, commit))
1682                         return 0;
1683         }
1684
1685         /*
1686          * We do not open the object yet; sort may only need refname
1687          * to do its job and the resulting list may yet to be pruned
1688          * by maxcount logic.
1689          */
1690         ref = new_ref_array_item(refname, oid->hash, flag);
1691         ref->commit = commit;
1692
1693         REALLOC_ARRAY(ref_cbdata->array->items, ref_cbdata->array->nr + 1);
1694         ref_cbdata->array->items[ref_cbdata->array->nr++] = ref;
1695         ref->kind = kind;
1696         return 0;
1697 }
1698
1699 /*  Free memory allocated for a ref_array_item */
1700 static void free_array_item(struct ref_array_item *item)
1701 {
1702         free((char *)item->symref);
1703         free(item);
1704 }
1705
1706 /* Free all memory allocated for ref_array */
1707 void ref_array_clear(struct ref_array *array)
1708 {
1709         int i;
1710
1711         for (i = 0; i < array->nr; i++)
1712                 free_array_item(array->items[i]);
1713         free(array->items);
1714         array->items = NULL;
1715         array->nr = array->alloc = 0;
1716 }
1717
1718 static void do_merge_filter(struct ref_filter_cbdata *ref_cbdata)
1719 {
1720         struct rev_info revs;
1721         int i, old_nr;
1722         struct ref_filter *filter = ref_cbdata->filter;
1723         struct ref_array *array = ref_cbdata->array;
1724         struct commit **to_clear = xcalloc(sizeof(struct commit *), array->nr);
1725
1726         init_revisions(&revs, NULL);
1727
1728         for (i = 0; i < array->nr; i++) {
1729                 struct ref_array_item *item = array->items[i];
1730                 add_pending_object(&revs, &item->commit->object, item->refname);
1731                 to_clear[i] = item->commit;
1732         }
1733
1734         filter->merge_commit->object.flags |= UNINTERESTING;
1735         add_pending_object(&revs, &filter->merge_commit->object, "");
1736
1737         revs.limited = 1;
1738         if (prepare_revision_walk(&revs))
1739                 die(_("revision walk setup failed"));
1740
1741         old_nr = array->nr;
1742         array->nr = 0;
1743
1744         for (i = 0; i < old_nr; i++) {
1745                 struct ref_array_item *item = array->items[i];
1746                 struct commit *commit = item->commit;
1747
1748                 int is_merged = !!(commit->object.flags & UNINTERESTING);
1749
1750                 if (is_merged == (filter->merge == REF_FILTER_MERGED_INCLUDE))
1751                         array->items[array->nr++] = array->items[i];
1752                 else
1753                         free_array_item(item);
1754         }
1755
1756         for (i = 0; i < old_nr; i++)
1757                 clear_commit_marks(to_clear[i], ALL_REV_FLAGS);
1758         clear_commit_marks(filter->merge_commit, ALL_REV_FLAGS);
1759         free(to_clear);
1760 }
1761
1762 /*
1763  * API for filtering a set of refs. Based on the type of refs the user
1764  * has requested, we iterate through those refs and apply filters
1765  * as per the given ref_filter structure and finally store the
1766  * filtered refs in the ref_array structure.
1767  */
1768 int filter_refs(struct ref_array *array, struct ref_filter *filter, unsigned int type)
1769 {
1770         struct ref_filter_cbdata ref_cbdata;
1771         int ret = 0;
1772         unsigned int broken = 0;
1773
1774         ref_cbdata.array = array;
1775         ref_cbdata.filter = filter;
1776
1777         if (type & FILTER_REFS_INCLUDE_BROKEN)
1778                 broken = 1;
1779         filter->kind = type & FILTER_REFS_KIND_MASK;
1780
1781         /*  Simple per-ref filtering */
1782         if (!filter->kind)
1783                 die("filter_refs: invalid type");
1784         else {
1785                 /*
1786                  * For common cases where we need only branches or remotes or tags,
1787                  * we only iterate through those refs. If a mix of refs is needed,
1788                  * we iterate over all refs and filter out required refs with the help
1789                  * of filter_ref_kind().
1790                  */
1791                 if (filter->kind == FILTER_REFS_BRANCHES)
1792                         ret = for_each_fullref_in("refs/heads/", ref_filter_handler, &ref_cbdata, broken);
1793                 else if (filter->kind == FILTER_REFS_REMOTES)
1794                         ret = for_each_fullref_in("refs/remotes/", ref_filter_handler, &ref_cbdata, broken);
1795                 else if (filter->kind == FILTER_REFS_TAGS)
1796                         ret = for_each_fullref_in("refs/tags/", ref_filter_handler, &ref_cbdata, broken);
1797                 else if (filter->kind & FILTER_REFS_ALL)
1798                         ret = for_each_fullref_in("", ref_filter_handler, &ref_cbdata, broken);
1799                 if (!ret && (filter->kind & FILTER_REFS_DETACHED_HEAD))
1800                         head_ref(ref_filter_handler, &ref_cbdata);
1801         }
1802
1803
1804         /*  Filters that need revision walking */
1805         if (filter->merge_commit)
1806                 do_merge_filter(&ref_cbdata);
1807
1808         return ret;
1809 }
1810
1811 static int cmp_ref_sorting(struct ref_sorting *s, struct ref_array_item *a, struct ref_array_item *b)
1812 {
1813         struct atom_value *va, *vb;
1814         int cmp;
1815         cmp_type cmp_type = used_atom[s->atom].type;
1816         int (*cmp_fn)(const char *, const char *);
1817
1818         get_ref_atom_value(a, s->atom, &va);
1819         get_ref_atom_value(b, s->atom, &vb);
1820         cmp_fn = s->ignore_case ? strcasecmp : strcmp;
1821         if (s->version)
1822                 cmp = versioncmp(va->s, vb->s);
1823         else if (cmp_type == FIELD_STR)
1824                 cmp = cmp_fn(va->s, vb->s);
1825         else {
1826                 if (va->ul < vb->ul)
1827                         cmp = -1;
1828                 else if (va->ul == vb->ul)
1829                         cmp = cmp_fn(a->refname, b->refname);
1830                 else
1831                         cmp = 1;
1832         }
1833
1834         return (s->reverse) ? -cmp : cmp;
1835 }
1836
1837 static struct ref_sorting *ref_sorting;
1838 static int compare_refs(const void *a_, const void *b_)
1839 {
1840         struct ref_array_item *a = *((struct ref_array_item **)a_);
1841         struct ref_array_item *b = *((struct ref_array_item **)b_);
1842         struct ref_sorting *s;
1843
1844         for (s = ref_sorting; s; s = s->next) {
1845                 int cmp = cmp_ref_sorting(s, a, b);
1846                 if (cmp)
1847                         return cmp;
1848         }
1849         return 0;
1850 }
1851
1852 void ref_array_sort(struct ref_sorting *sorting, struct ref_array *array)
1853 {
1854         ref_sorting = sorting;
1855         QSORT(array->items, array->nr, compare_refs);
1856 }
1857
1858 static void append_literal(const char *cp, const char *ep, struct ref_formatting_state *state)
1859 {
1860         struct strbuf *s = &state->stack->output;
1861
1862         while (*cp && (!ep || cp < ep)) {
1863                 if (*cp == '%') {
1864                         if (cp[1] == '%')
1865                                 cp++;
1866                         else {
1867                                 int ch = hex2chr(cp + 1);
1868                                 if (0 <= ch) {
1869                                         strbuf_addch(s, ch);
1870                                         cp += 3;
1871                                         continue;
1872                                 }
1873                         }
1874                 }
1875                 strbuf_addch(s, *cp);
1876                 cp++;
1877         }
1878 }
1879
1880 void format_ref_array_item(struct ref_array_item *info, const char *format,
1881                            int quote_style, struct strbuf *final_buf)
1882 {
1883         const char *cp, *sp, *ep;
1884         struct ref_formatting_state state = REF_FORMATTING_STATE_INIT;
1885
1886         state.quote_style = quote_style;
1887         push_stack_element(&state.stack);
1888
1889         for (cp = format; *cp && (sp = find_next(cp)); cp = ep + 1) {
1890                 struct atom_value *atomv;
1891
1892                 ep = strchr(sp, ')');
1893                 if (cp < sp)
1894                         append_literal(cp, sp, &state);
1895                 get_ref_atom_value(info, parse_ref_filter_atom(sp + 2, ep), &atomv);
1896                 atomv->handler(atomv, &state);
1897         }
1898         if (*cp) {
1899                 sp = cp + strlen(cp);
1900                 append_literal(cp, sp, &state);
1901         }
1902         if (need_color_reset_at_eol) {
1903                 struct atom_value resetv;
1904                 char color[COLOR_MAXLEN] = "";
1905
1906                 if (color_parse("reset", color) < 0)
1907                         die("BUG: couldn't parse 'reset' as a color");
1908                 resetv.s = color;
1909                 append_atom(&resetv, &state);
1910         }
1911         if (state.stack->prev)
1912                 die(_("format: %%(end) atom missing"));
1913         strbuf_addbuf(final_buf, &state.stack->output);
1914         pop_stack_element(&state.stack);
1915 }
1916
1917 void show_ref_array_item(struct ref_array_item *info, const char *format, int quote_style)
1918 {
1919         struct strbuf final_buf = STRBUF_INIT;
1920
1921         format_ref_array_item(info, format, quote_style, &final_buf);
1922         fwrite(final_buf.buf, 1, final_buf.len, stdout);
1923         strbuf_release(&final_buf);
1924         putchar('\n');
1925 }
1926
1927 /*  If no sorting option is given, use refname to sort as default */
1928 struct ref_sorting *ref_default_sorting(void)
1929 {
1930         static const char cstr_name[] = "refname";
1931
1932         struct ref_sorting *sorting = xcalloc(1, sizeof(*sorting));
1933
1934         sorting->next = NULL;
1935         sorting->atom = parse_ref_filter_atom(cstr_name, cstr_name + strlen(cstr_name));
1936         return sorting;
1937 }
1938
1939 int parse_opt_ref_sorting(const struct option *opt, const char *arg, int unset)
1940 {
1941         struct ref_sorting **sorting_tail = opt->value;
1942         struct ref_sorting *s;
1943         int len;
1944
1945         if (!arg) /* should --no-sort void the list ? */
1946                 return -1;
1947
1948         s = xcalloc(1, sizeof(*s));
1949         s->next = *sorting_tail;
1950         *sorting_tail = s;
1951
1952         if (*arg == '-') {
1953                 s->reverse = 1;
1954                 arg++;
1955         }
1956         if (skip_prefix(arg, "version:", &arg) ||
1957             skip_prefix(arg, "v:", &arg))
1958                 s->version = 1;
1959         len = strlen(arg);
1960         s->atom = parse_ref_filter_atom(arg, arg+len);
1961         return 0;
1962 }
1963
1964 int parse_opt_merge_filter(const struct option *opt, const char *arg, int unset)
1965 {
1966         struct ref_filter *rf = opt->value;
1967         unsigned char sha1[20];
1968
1969         rf->merge = starts_with(opt->long_name, "no")
1970                 ? REF_FILTER_MERGED_OMIT
1971                 : REF_FILTER_MERGED_INCLUDE;
1972
1973         if (get_sha1(arg, sha1))
1974                 die(_("malformed object name %s"), arg);
1975
1976         rf->merge_commit = lookup_commit_reference_gently(sha1, 0);
1977         if (!rf->merge_commit)
1978                 return opterror(opt, "must point to a commit", 0);
1979
1980         return 0;
1981 }