ref-filter: add return value to parsers

Continue removing die() calls from ref-filter formatting logic, so that it could be used by other commands. Change the signature of parsers by adding return value and strbuf parameter for error message. Return value equals 0 upon success and -1 upon failure. Upon failure, error message is appended to the strbuf. Signed-off-by: Olga Telezhnaia <olyatelezhnaya@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Olga Telezhnaya committed Mar 29, 2018 at 12:49 UTC 74efea9474149b16bbc17f89df00cd3d117f763f
1 file changed +89 -49
ref-filter.c
+89 -49
@@ -114,22 +114,25 @@ static int strbuf_addf_ret(struct strbuf *sb, int ret, const char *fmt, ...)
114 return ret;
115 }
116
117 -static void color_atom_parser(const struct ref_format *format, struct used_atom *atom, const char *color_value)
117 +static int color_atom_parser(const struct ref_format *format, struct used_atom *atom,
118 + const char *color_value, struct strbuf *err)
119 {
120 if (!color_value)
120 - die(_("expected format: %%(color:<color>)"));
121 + return strbuf_addf_ret(err, -1, _("expected format: %%(color:<color>)"));
122 if (color_parse(color_value, atom->u.color) < 0)
122 - die(_("unrecognized color: %%(color:%s)"), color_value);
123 + return strbuf_addf_ret(err, -1, _("unrecognized color: %%(color:%s)"),
124 + color_value);
125 /*
126 * We check this after we've parsed the color, which lets us complain
127 * about syntactically bogus color names even if they won't be used.
128 */
129 if (!want_color(format->use_color))
130 color_parse("", atom->u.color);
131 + return 0;
132 }
133
131 -static void refname_atom_parser_internal(struct refname_atom *atom,
132 - const char *arg, const char *name)
134 +static int refname_atom_parser_internal(struct refname_atom *atom, const char *arg,
135 + const char *name, struct strbuf *err)
136 {
137 if (!arg)
138 atom->option = R_NORMAL;
@@ -139,16 +142,18 @@ static void refname_atom_parser_internal(struct refname_atom *atom,
142 skip_prefix(arg, "strip=", &arg)) {
143 atom->option = R_LSTRIP;
144 if (strtol_i(arg, 10, &atom->lstrip))
142 - die(_("Integer value expected refname:lstrip=%s"), arg);
145 + return strbuf_addf_ret(err, -1, _("Integer value expected refname:lstrip=%s"), arg);
146 } else if (skip_prefix(arg, "rstrip=", &arg)) {
147 atom->option = R_RSTRIP;
148 if (strtol_i(arg, 10, &atom->rstrip))
146 - die(_("Integer value expected refname:rstrip=%s"), arg);
149 + return strbuf_addf_ret(err, -1, _("Integer value expected refname:rstrip=%s"), arg);
150 } else
148 - die(_("unrecognized %%(%s) argument: %s"), name, arg);
151 + return strbuf_addf_ret(err, -1, _("unrecognized %%(%s) argument: %s"), name, arg);
152 + return 0;
153 }
154
151 -static void remote_ref_atom_parser(const struct ref_format *format, struct used_atom *atom, const char *arg)
155 +static int remote_ref_atom_parser(const struct ref_format *format, struct used_atom *atom,
156 + const char *arg, struct strbuf *err)
157 {
158 struct string_list params = STRING_LIST_INIT_DUP;
159 int i;
@@ -158,9 +163,8 @@ static void remote_ref_atom_parser(const struct ref_format *format, struct used_
163
164 if (!arg) {
165 atom->u.remote_ref.option = RR_REF;
161 - refname_atom_parser_internal(&atom->u.remote_ref.refname,
162 - arg, atom->name);
163 - return;
166 + return refname_atom_parser_internal(&atom->u.remote_ref.refname,
167 + arg, atom->name, err);
168 }
169
170 atom->u.remote_ref.nobracket = 0;
@@ -183,29 +187,38 @@ static void remote_ref_atom_parser(const struct ref_format *format, struct used_
187 atom->u.remote_ref.push_remote = 1;
188 } else {
189 atom->u.remote_ref.option = RR_REF;
186 - refname_atom_parser_internal(&atom->u.remote_ref.refname,
187 - arg, atom->name);
190 + if (refname_atom_parser_internal(&atom->u.remote_ref.refname,
191 + arg, atom->name, err)) {
192 + string_list_clear(&params, 0);
193 + return -1;
194 + }
195 }
196 }
197
198 string_list_clear(&params, 0);
199 + return 0;
200 }
201
194 -static void body_atom_parser(const struct ref_format *format, struct used_atom *atom, const char *arg)
202 +static int body_atom_parser(const struct ref_format *format, struct used_atom *atom,
203 + const char *arg, struct strbuf *err)
204 {
205 if (arg)
197 - die(_("%%(body) does not take arguments"));
206 + return strbuf_addf_ret(err, -1, _("%%(body) does not take arguments"));
207 atom->u.contents.option = C_BODY_DEP;
208 + return 0;
209 }
210
201 -static void subject_atom_parser(const struct ref_format *format, struct used_atom *atom, const char *arg)
211 +static int subject_atom_parser(const struct ref_format *format, struct used_atom *atom,
212 + const char *arg, struct strbuf *err)
213 {
214 if (arg)
204 - die(_("%%(subject) does not take arguments"));
215 + return strbuf_addf_ret(err, -1, _("%%(subject) does not take arguments"));
216 atom->u.contents.option = C_SUB;
217 + return 0;
218 }
219
208 -static void trailers_atom_parser(const struct ref_format *format, struct used_atom *atom, const char *arg)
220 +static int trailers_atom_parser(const struct ref_format *format, struct used_atom *atom,
221 + const char *arg, struct strbuf *err)
222 {
223 struct string_list params = STRING_LIST_INIT_DUP;
224 int i;
@@ -218,15 +231,20 @@ static void trailers_atom_parser(const struct ref_format *format, struct used_at
231 atom->u.contents.trailer_opts.unfold = 1;
232 else if (!strcmp(s, "only"))
233 atom->u.contents.trailer_opts.only_trailers = 1;
221 - else
222 - die(_("unknown %%(trailers) argument: %s"), s);
234 + else {
235 + strbuf_addf(err, _("unknown %%(trailers) argument: %s"), s);
236 + string_list_clear(&params, 0);
237 + return -1;
238 + }
239 }
240 }
241 atom->u.contents.option = C_TRAILERS;
242 string_list_clear(&params, 0);
243 + return 0;
244 }
245
229 -static void contents_atom_parser(const struct ref_format *format, struct used_atom *atom, const char *arg)
246 +static int contents_atom_parser(const struct ref_format *format, struct used_atom *atom,
247 + const char *arg, struct strbuf *err)
248 {
249 if (!arg)
250 atom->u.contents.option = C_BARE;
@@ -238,16 +256,19 @@ static void contents_atom_parser(const struct ref_format *format, struct used_at
256 atom->u.contents.option = C_SUB;
257 else if (skip_prefix(arg, "trailers", &arg)) {
258 skip_prefix(arg, ":", &arg);
241 - trailers_atom_parser(format, atom, *arg ? arg : NULL);
259 + if (trailers_atom_parser(format, atom, *arg ? arg : NULL, err))
260 + return -1;
261 } else if (skip_prefix(arg, "lines=", &arg)) {
262 atom->u.contents.option = C_LINES;
263 if (strtoul_ui(arg, 10, &atom->u.contents.nlines))
245 - die(_("positive value expected contents:lines=%s"), arg);
264 + return strbuf_addf_ret(err, -1, _("positive value expected contents:lines=%s"), arg);
265 } else
247 - die(_("unrecognized %%(contents) argument: %s"), arg);
266 + return strbuf_addf_ret(err, -1, _("unrecognized %%(contents) argument: %s"), arg);
267 + return 0;
268 }
269
250 -static void objectname_atom_parser(const struct ref_format *format, struct used_atom *atom, const char *arg)
270 +static int objectname_atom_parser(const struct ref_format *format, struct used_atom *atom,
271 + const char *arg, struct strbuf *err)
272 {
273 if (!arg)
274 atom->u.objectname.option = O_FULL;
@@ -257,16 +278,18 @@ static void objectname_atom_parser(const struct ref_format *format, struct used_
278 atom->u.objectname.option = O_LENGTH;
279 if (strtoul_ui(arg, 10, &atom->u.objectname.length) ||
280 atom->u.objectname.length == 0)
260 - die(_("positive value expected objectname:short=%s"), arg);
281 + return strbuf_addf_ret(err, -1, _("positive value expected objectname:short=%s"), arg);
282 if (atom->u.objectname.length < MINIMUM_ABBREV)
283 atom->u.objectname.length = MINIMUM_ABBREV;
284 } else
264 - die(_("unrecognized %%(objectname) argument: %s"), arg);
285 + return strbuf_addf_ret(err, -1, _("unrecognized %%(objectname) argument: %s"), arg);
286 + return 0;
287 }
288
267 -static void refname_atom_parser(const struct ref_format *format, struct used_atom *atom, const char *arg)
289 +static int refname_atom_parser(const struct ref_format *format, struct used_atom *atom,
290 + const char *arg, struct strbuf *err)
291 {
269 - refname_atom_parser_internal(&atom->u.refname, arg, atom->name);
292 + return refname_atom_parser_internal(&atom->u.refname, arg, atom->name, err);
293 }
294
295 static align_type parse_align_position(const char *s)
@@ -280,7 +303,8 @@ static align_type parse_align_position(const char *s)
303 return -1;
304 }
305
283 -static void align_atom_parser(const struct ref_format *format, struct used_atom *atom, const char *arg)
306 +static int align_atom_parser(const struct ref_format *format, struct used_atom *atom,
307 + const char *arg, struct strbuf *err)
308 {
309 struct align *align = &atom->u.align;
310 struct string_list params = STRING_LIST_INIT_DUP;
@@ -288,7 +312,7 @@ static void align_atom_parser(const struct ref_format *format, struct used_atom
312 unsigned int width = ~0U;
313
314 if (!arg)
291 - die(_("expected format: %%(align:<width>,<position>)"));
315 + return strbuf_addf_ret(err, -1, _("expected format: %%(align:<width>,<position>)"));
316
317 align->position = ALIGN_LEFT;
318
@@ -299,49 +323,65 @@ static void align_atom_parser(const struct ref_format *format, struct used_atom
323
324 if (skip_prefix(s, "position=", &s)) {
325 position = parse_align_position(s);
302 - if (position < 0)
303 - die(_("unrecognized position:%s"), s);
326 + if (position < 0) {
327 + strbuf_addf(err, _("unrecognized position:%s"), s);
328 + string_list_clear(&params, 0);
329 + return -1;
330 + }
331 align->position = position;
332 } else if (skip_prefix(s, "width=", &s)) {
306 - if (strtoul_ui(s, 10, &width))
307 - die(_("unrecognized width:%s"), s);
333 + if (strtoul_ui(s, 10, &width)) {
334 + strbuf_addf(err, _("unrecognized width:%s"), s);
335 + string_list_clear(&params, 0);
336 + return -1;
337 + }
338 } else if (!strtoul_ui(s, 10, &width))
339 ;
340 else if ((position = parse_align_position(s)) >= 0)
341 align->position = position;
312 - else
313 - die(_("unrecognized %%(align) argument: %s"), s);
342 + else {
343 + strbuf_addf(err, _("unrecognized %%(align) argument: %s"), s);
344 + string_list_clear(&params, 0);
345 + return -1;
346 + }
347 }
348
316 - if (width == ~0U)
317 - die(_("positive width expected with the %%(align) atom"));
349 + if (width == ~0U) {
350 + string_list_clear(&params, 0);
351 + return strbuf_addf_ret(err, -1, _("positive width expected with the %%(align) atom"));
352 + }
353 align->width = width;
354 string_list_clear(&params, 0);
355 + return 0;
356 }
357
322 -static void if_atom_parser(const struct ref_format *format, struct used_atom *atom, const char *arg)
358 +static int if_atom_parser(const struct ref_format *format, struct used_atom *atom,
359 + const char *arg, struct strbuf *err)
360 {
361 if (!arg) {
362 atom->u.if_then_else.cmp_status = COMPARE_NONE;
326 - return;
363 + return 0;
364 } else if (skip_prefix(arg, "equals=", &atom->u.if_then_else.str)) {
365 atom->u.if_then_else.cmp_status = COMPARE_EQUAL;
366 } else if (skip_prefix(arg, "notequals=", &atom->u.if_then_else.str)) {
367 atom->u.if_then_else.cmp_status = COMPARE_UNEQUAL;
331 - } else {
332 - die(_("unrecognized %%(if) argument: %s"), arg);
333 - }
368 + } else
369 + return strbuf_addf_ret(err, -1, _("unrecognized %%(if) argument: %s"), arg);
370 + return 0;
371 }
372
336 -static void head_atom_parser(const struct ref_format *format, struct used_atom *atom, const char *arg)
373 +static int head_atom_parser(const struct ref_format *format, struct used_atom *atom,
374 + const char *arg, struct strbuf *unused_err)
375 {
376 atom->u.head = resolve_refdup("HEAD", RESOLVE_REF_READING, NULL, NULL);
377 + return 0;
378 }
379
380 static struct {
381 const char *name;
382 cmp_type cmp_type;
344 - void (*parser)(const struct ref_format *format, struct used_atom *atom, const char *arg);
383 + int (*parser)(const struct ref_format *format, struct used_atom *atom,
384 + const char *arg, struct strbuf *err);
385 } valid_atom[] = {
386 { "refname" , FIELD_STR, refname_atom_parser },
387 { "objecttype" },
@@ -468,8 +508,8 @@ static int parse_ref_filter_atom(const struct ref_format *format,
508 }
509 }
510 memset(&used_atom[at].u, 0, sizeof(used_atom[at].u));
471 - if (valid_atom[i].parser)
472 - valid_atom[i].parser(format, &used_atom[at], arg);
511 + if (valid_atom[i].parser && valid_atom[i].parser(format, &used_atom[at], arg, err))
512 + return -1;
513 if (*atom == '*')
514 need_tagged = 1;
515 if (!strcmp(valid_atom[i].name, "symref"))