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(¶ms, 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(¶ms, 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 */