@@ -282,6 +282,54 @@ static void show_name(struct strbuf *sb, const struct name_decoration *decoratio
strbuf_addstr(sb, decoration->name);
}
+struct format_decorations_context {
+ struct strbuf *sb;
+ int use_color;
+ const char *prefix;
+ const char *separator;
+ const char *suffix;
+ const char *color_commit;
+ const char *color_reset;
+ const struct name_decoration *current_and_HEAD;
+};
+
+static int append_decoration(const struct name_decoration *d,
+ void *data)
+{
+ struct format_decorations_context *ctx = data;
+ /*
+ * When both current and HEAD are there, only
+ * show HEAD->current where HEAD would have
+ * appeared, skipping the entry for current.
+ */
+ if (d != ctx->current_and_HEAD) {
+ strbuf_addstr(ctx->sb, ctx->color_commit);
+ strbuf_addstr(ctx->sb, ctx->prefix);
+ strbuf_addstr(ctx->sb, ctx->color_reset);
+ strbuf_addstr(ctx->sb, decorate_get_color(ctx->use_color, d->type));
+ if (d->type == DECORATION_REF_TAG)
+ strbuf_addstr(ctx->sb, "tag: ");
+
+ show_name(ctx->sb, d);
+
+ if (ctx->current_and_HEAD &&
+ d->type == DECORATION_REF_HEAD) {
+ strbuf_addstr(ctx->sb, " -> ");
+ strbuf_addstr(ctx->sb, ctx->color_reset);
+ strbuf_addstr(ctx->sb,
+ decorate_get_color(
+ ctx->use_color,
+ ctx->current_and_HEAD->type));
+ show_name(ctx->sb, ctx->current_and_HEAD);
+ }
+ strbuf_addstr(ctx->sb, ctx->color_reset);
+
+ ctx->prefix = ctx->separator;
+ }
+
+ return 0;
+}
+
/*
* The caller makes sure there is no funny color before calling.
* format_decorations_extended makes sure the same after return.
@@ -294,49 +342,42 @@ void format_decorations_extended(struct strbuf *sb,
const char *suffix)
{
const struct name_decoration *decoration;
- const struct name_decoration *current_and_HEAD;
- const char *color_commit =
- diff_get_color(use_color, DIFF_COMMIT);
- const char *color_reset =
- decorate_get_color(use_color, DECORATION_NONE);
+ struct format_decorations_context ctx = {
+ .sb = sb,
+ .use_color = use_color,
+ .prefix = prefix,
+ .separator = separator,
+ .suffix = suffix,
+ .color_commit = diff_get_color(use_color, DIFF_COMMIT),
+ .color_reset = decorate_get_color(use_color, DECORATION_NONE),
+ };
decoration = get_name_decoration(&commit->object);
if (!decoration)
return;
- current_and_HEAD = current_pointed_by_HEAD(decoration);
- while (decoration) {
- /*
- * When both current and HEAD are there, only
- * show HEAD->current where HEAD would have
- * appeared, skipping the entry for current.
- */
- if (decoration != current_and_HEAD) {
- strbuf_addstr(sb, color_commit);
- strbuf_addstr(sb, prefix);
- strbuf_addstr(sb, color_reset);
- strbuf_addstr(sb, decorate_get_color(use_color, decoration->type));
- if (decoration->type == DECORATION_REF_TAG)
- strbuf_addstr(sb, "tag: ");
-
- show_name(sb, decoration);
-
- if (current_and_HEAD &&
- decoration->type == DECORATION_REF_HEAD) {
- strbuf_addstr(sb, " -> ");
- strbuf_addstr(sb, color_reset);
- strbuf_addstr(sb, decorate_get_color(use_color, current_and_HEAD->type));
- show_name(sb, current_and_HEAD);
- }
- strbuf_addstr(sb, color_reset);
+ ctx.current_and_HEAD = current_pointed_by_HEAD(decoration);
- prefix = separator;
- }
+ for_each_decoration(commit, append_decoration, &ctx);
+
+ strbuf_addstr(sb, ctx.color_commit);
+ strbuf_addstr(sb, ctx.suffix);
+ strbuf_addstr(sb, ctx.color_reset);
+}
+
+int for_each_decoration(const struct commit *c, decoration_fn fn, void *data)
+{
+ const struct name_decoration *decoration;
+
+ decoration = get_name_decoration(&c->object);
+ while (decoration) {
+ int res;
+ if ((res = fn(decoration, data)))
+ return res;
decoration = decoration->next;
}
- strbuf_addstr(sb, color_commit);
- strbuf_addstr(sb, suffix);
- strbuf_addstr(sb, color_reset);
+
+ return 0;
}
void show_decorations(struct rev_info *opt, struct commit *commit)
@@ -35,4 +35,8 @@ void fmt_output_commit(struct strbuf *, struct commit *, struct rev_info *);
void fmt_output_subject(struct strbuf *, const char *subject, struct rev_info *);
void fmt_output_email_subject(struct strbuf *, struct rev_info *);
+typedef int decoration_fn(const struct name_decoration *d,
+ void *data);
+int for_each_decoration(const struct commit *c, decoration_fn fn, void *data);
+
#endif