Re: [RFC 3/4] ref-filter: change parsing function error handling

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



2018-03-13 22:18 GMT+03:00 Martin Ågren <martin.agren@xxxxxxxxx>:
> On 13 March 2018 at 11:16, Olga Telezhnaya <olyatelezhnaya@xxxxxxxxx> wrote:
>> Continue removing any printing from ref-filter formatting logic,
>> so that it could be more general.
>>
>> Change the signature of parse_ref_filter_atom() by changing return value,
>> adding previous return value to function parameter and also adding
>> strbuf parameter for error message.
>
> I think the current return value is always non-negative. Maybe it would
> be easier to leave the return value as-is, except return negative on
> error? Unless I am missing something?

That's interesting. I like your idea, but let's see what other people think.
If others agree with us, I am ready to implement your solution.

>
>>
>> Signed-off-by: Olga Telezhnaia <olyatelezhnaya@xxxxxxxxx>
>> ---
>>  ref-filter.c | 45 ++++++++++++++++++++++++++++++++-------------
>>  1 file changed, 32 insertions(+), 13 deletions(-)
>>
>> diff --git a/ref-filter.c b/ref-filter.c
>> index 07bedc636398c..e146215bf1e64 100644
>> --- a/ref-filter.c
>> +++ b/ref-filter.c
>> @@ -397,7 +397,8 @@ struct atom_value {
>>   * Used to parse format string and sort specifiers
>>   */
>>  static int parse_ref_filter_atom(const struct ref_format *format,
>> -                                const char *atom, const char *ep)
>> +                                const char *atom, const char *ep, int *res,
>> +                                struct strbuf *err)
>>  {
>>         const char *sp;
>>         const char *arg;
>> @@ -406,14 +407,18 @@ static int parse_ref_filter_atom(const struct ref_format *format,
>>         sp = atom;
>>         if (*sp == '*' && sp < ep)
>>                 sp++; /* deref */
>> -       if (ep <= sp)
>> -               die(_("malformed field name: %.*s"), (int)(ep-atom), atom);
>> +       if (ep <= sp) {
>> +               strbuf_addf(err, _("malformed field name: %.*s"), (int)(ep-atom), atom);
>> +               return -1;
>> +       }
>>
>>         /* Do we have the atom already used elsewhere? */
>>         for (i = 0; i < used_atom_cnt; i++) {
>>                 int len = strlen(used_atom[i].name);
>> -               if (len == ep - atom && !memcmp(used_atom[i].name, atom, len))
>> -                       return i;
>> +               if (len == ep - atom && !memcmp(used_atom[i].name, atom, len)) {
>> +                       *res = i;
>> +                       return 0;
>> +               }
>>         }
>
> If you did so, this hunk above would not need to be changed ...
>
>> @@ -458,7 +465,8 @@ static int parse_ref_filter_atom(const struct ref_format *format,
>>                 need_tagged = 1;
>>         if (!strcmp(valid_atom[i].name, "symref"))
>>                 need_symref = 1;
>> -       return at;
>> +       *res = at;
>> +       return 0;
>>  }
>
> ... nor this one above ...
>
>>                 if (!ep)
>>                         return error(_("malformed format string %s"), sp);
>>                 /* sp points at "%(" and ep points at the closing ")" */
>> -               at = parse_ref_filter_atom(format, sp + 2, ep);
>> +               if (parse_ref_filter_atom(format, sp + 2, ep, &at, &err))
>> +                       die("%s", err.buf);
>
> And this would be more like "if (at < 0) die(...)".
>
>>         for (cp = format->format; *cp && (sp = find_next(cp)); cp = ep + 1) {
>>                 struct atom_value *atomv;
>> +               struct strbuf err = STRBUF_INIT;
>> +               int pos;
>>
>>                 ep = strchr(sp, ')');
>>                 if (cp < sp)
>>                         append_literal(cp, sp, &state);
>> -               get_ref_atom_value(info,
>> -                                  parse_ref_filter_atom(format, sp + 2, ep),
>> -                                  &atomv);
>> +               if (parse_ref_filter_atom(format, sp + 2, ep, &pos, &err))
>> +                       return -1;
>> +               get_ref_atom_value(info, pos, &atomv);
>>                 if (atomv->handler(atomv, &state, error_buf))
>>                         return -1;
>> +               strbuf_release(&err);
>
> This looks leaky: if we get an error, we've got something in the buffer
> but we do not release it because we return early. Stepping back a bit, I
> wonder why we do not do anything at all with "err". Stepping back a bit
> more :-) I wonder if you could get rid of "err" and pass "error_buf" to
> parse_ref_filter_atom() instead. Our caller would like to have access to
> the error string?

Fully agree, I don't know why I decided to create one more buffer. Fixed.

>
> This ties back to my comment on the first patch -- "return negative if
> and only if you add some error string to the buffer" might be a useful
> rule?
>
> Martin




[Index of Archives]     [Linux Kernel Development]     [Gcc Help]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [V4L]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Fedora Users]

  Powered by Linux