ref-filter: pass ref_format struct to atom parsers

The callback for parsing each formatting atom gets to see only the atom struct (which it's filling in) and the text to be parsed. This doesn't leave any room for it to behave differently based on context known only to the ref_format. We can solve this by passing in the surrounding ref_format to each parser. Note that this makes things slightly awkward for sort strings, which parse atoms without having a ref_format. We'll solve that by using a dummy ref_format with default parameters. Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Jeff King committed Jul 13, 2017 at 11:06 UTC ab7ded34d6a9a5d4c8bf073cb9627b8054f430cf
1 file changed +25 -17
ref-filter.c
+25 -17
@@ -98,7 +98,7 @@ static struct used_atom {
98 } *used_atom;
99 static int used_atom_cnt, need_tagged, need_symref;
100
101 -static void color_atom_parser(struct used_atom *atom, const char *color_value)
101 +static void color_atom_parser(const struct ref_format *format, struct used_atom *atom, const char *color_value)
102 {
103 if (!color_value)
104 die(_("expected format: %%(color:<color>)"));
@@ -126,7 +126,7 @@ static void refname_atom_parser_internal(struct refname_atom *atom,
126 die(_("unrecognized %%(%s) argument: %s"), name, arg);
127 }
128
129 -static void remote_ref_atom_parser(struct used_atom *atom, const char *arg)
129 +static void remote_ref_atom_parser(const struct ref_format *format, struct used_atom *atom, const char *arg)
130 {
131 struct string_list params = STRING_LIST_INIT_DUP;
132 int i;
@@ -160,28 +160,28 @@ static void remote_ref_atom_parser(struct used_atom *atom, const char *arg)
160 string_list_clear(&params, 0);
161 }
162
163 -static void body_atom_parser(struct used_atom *atom, const char *arg)
163 +static void body_atom_parser(const struct ref_format *format, struct used_atom *atom, const char *arg)
164 {
165 if (arg)
166 die(_("%%(body) does not take arguments"));
167 atom->u.contents.option = C_BODY_DEP;
168 }
169
170 -static void subject_atom_parser(struct used_atom *atom, const char *arg)
170 +static void subject_atom_parser(const struct ref_format *format, struct used_atom *atom, const char *arg)
171 {
172 if (arg)
173 die(_("%%(subject) does not take arguments"));
174 atom->u.contents.option = C_SUB;
175 }
176
177 -static void trailers_atom_parser(struct used_atom *atom, const char *arg)
177 +static void trailers_atom_parser(const struct ref_format *format, struct used_atom *atom, const char *arg)
178 {
179 if (arg)
180 die(_("%%(trailers) does not take arguments"));
181 atom->u.contents.option = C_TRAILERS;
182 }
183
184 -static void contents_atom_parser(struct used_atom *atom, const char *arg)
184 +static void contents_atom_parser(const struct ref_format *format, struct used_atom *atom, const char *arg)
185 {
186 if (!arg)
187 atom->u.contents.option = C_BARE;
@@ -201,7 +201,7 @@ static void contents_atom_parser(struct used_atom *atom, const char *arg)
201 die(_("unrecognized %%(contents) argument: %s"), arg);
202 }
203
204 -static void objectname_atom_parser(struct used_atom *atom, const char *arg)
204 +static void objectname_atom_parser(const struct ref_format *format, struct used_atom *atom, const char *arg)
205 {
206 if (!arg)
207 atom->u.objectname.option = O_FULL;
@@ -218,7 +218,7 @@ static void objectname_atom_parser(struct used_atom *atom, const char *arg)
218 die(_("unrecognized %%(objectname) argument: %s"), arg);
219 }
220
221 -static void refname_atom_parser(struct used_atom *atom, const char *arg)
221 +static void refname_atom_parser(const struct ref_format *format, struct used_atom *atom, const char *arg)
222 {
223 refname_atom_parser_internal(&atom->u.refname, arg, atom->name);
224 }
@@ -234,7 +234,7 @@ static align_type parse_align_position(const char *s)
234 return -1;
235 }
236
237 -static void align_atom_parser(struct used_atom *atom, const char *arg)
237 +static void align_atom_parser(const struct ref_format *format, struct used_atom *atom, const char *arg)
238 {
239 struct align *align = &atom->u.align;
240 struct string_list params = STRING_LIST_INIT_DUP;
@@ -273,7 +273,7 @@ static void align_atom_parser(struct used_atom *atom, const char *arg)
273 string_list_clear(&params, 0);
274 }
275
276 -static void if_atom_parser(struct used_atom *atom, const char *arg)
276 +static void if_atom_parser(const struct ref_format *format, struct used_atom *atom, const char *arg)
277 {
278 if (!arg) {
279 atom->u.if_then_else.cmp_status = COMPARE_NONE;
@@ -287,7 +287,7 @@ static void if_atom_parser(struct used_atom *atom, const char *arg)
287 }
288 }
289
290 -static void head_atom_parser(struct used_atom *atom, const char *arg)
290 +static void head_atom_parser(const struct ref_format *format, struct used_atom *atom, const char *arg)
291 {
292 struct object_id unused;
293
@@ -297,7 +297,7 @@ static void head_atom_parser(struct used_atom *atom, const char *arg)
297 static struct {
298 const char *name;
299 cmp_type cmp_type;
300 - void (*parser)(struct used_atom *atom, const char *arg);
300 + void (*parser)(const struct ref_format *format, struct used_atom *atom, const char *arg);
301 } valid_atom[] = {
302 { "refname" , FIELD_STR, refname_atom_parser },
303 { "objecttype" },
@@ -364,7 +364,8 @@ struct atom_value {
364 /*
365 * Used to parse format string and sort specifiers
366 */
367 -static int parse_ref_filter_atom(const char *atom, const char *ep)
367 +static int parse_ref_filter_atom(const struct ref_format *format,
368 + const char *atom, const char *ep)
369 {
370 const char *sp;
371 const char *arg;
@@ -412,7 +413,7 @@ static int parse_ref_filter_atom(const char *atom, const char *ep)
413 arg = used_atom[at].name + (arg - atom) + 1;
414 memset(&used_atom[at].u, 0, sizeof(used_atom[at].u));
415 if (valid_atom[i].parser)
415 - valid_atom[i].parser(&used_atom[at], arg);
416 + valid_atom[i].parser(format, &used_atom[at], arg);
417 if (*atom == '*')
418 need_tagged = 1;
419 if (!strcmp(valid_atom[i].name, "symref"))
@@ -668,7 +669,7 @@ int verify_ref_format(struct ref_format *format)
669 if (!ep)
670 return error(_("malformed format string %s"), sp);
671 /* sp points at "%(" and ep points at the closing ")" */
671 - at = parse_ref_filter_atom(sp + 2, ep);
672 + at = parse_ref_filter_atom(format, sp + 2, ep);
673 cp = ep + 1;
674
675 if (skip_prefix(used_atom[at].name, "color:", &color))
@@ -2075,7 +2076,9 @@ void format_ref_array_item(struct ref_array_item *info,
2076 ep = strchr(sp, ')');
2077 if (cp < sp)
2078 append_literal(cp, sp, &state);
2078 - get_ref_atom_value(info, parse_ref_filter_atom(sp + 2, ep), &atomv);
2079 + get_ref_atom_value(info,
2080 + parse_ref_filter_atom(format, sp + 2, ep),
2081 + &atomv);
2082 atomv->handler(atomv, &state);
2083 }
2084 if (*cp) {
@@ -2116,8 +2119,13 @@ void pretty_print_ref(const char *name, const unsigned char *sha1,
2119
2120 static int parse_sorting_atom(const char *atom)
2121 {
2122 + /*
2123 + * This parses an atom using a dummy ref_format, since we don't
2124 + * actually care about the formatting details.
2125 + */
2126 + struct ref_format dummy = REF_FORMAT_INIT;
2127 const char *end = atom + strlen(atom);
2120 - return parse_ref_filter_atom(atom, end);
2128 + return parse_ref_filter_atom(&dummy, atom, end);
2129 }
2130
2131 /* If no sorting option is given, use refname to sort as default */