On 09/27/2016 09:19 PM, Jeff King wrote: > [...] > I'm going to ramble for a minute, and I don't think it's worth exploring > for this patch series in particular, so feel free to ignore me. > > I think this error concept could be extended fairly elegantly with > something like: > > typedef void (*err_fn)(void *, const char *fmt, va_list ap) > struct error_context { > err_fn fn; > void *data; > }; > > int report_error(struct error_context *err, const char *fmt, ...) > { > if (err->fn) { > va_list ap; > va_start(ap, fmt); > err->fn(err->data, fmt, ap); > va_end(ap); > } > return -1; > } I like this idea. It's nicely flexible (more so than the `struct strbuf *err` that is currently used for reference transactions) without being cumbersome. > Then low-level functions just take a context and do: > > return report_error(&err, "some error: %s", foo); > > And then the callers would pick one of a few generic error contexts: > > - passing NULL silences the errors > > - a global for chaining to error, like: > > struct error_context print_errors = { > error, /* actually a wrapper to handle va_list and NULL data */ > NULL > }; There could also be a global for chaining to `warn()` or `die()`. > [...] Michael