diff options
Diffstat (limited to 'ref-filter.c')
-rw-r--r-- | ref-filter.c | 108 |
1 files changed, 64 insertions, 44 deletions
diff --git a/ref-filter.c b/ref-filter.c index ae6ecbd1cf..bc591f4f3d 100644 --- a/ref-filter.c +++ b/ref-filter.c @@ -97,14 +97,19 @@ static struct used_atom { } u; } *used_atom; static int used_atom_cnt, need_tagged, need_symref; -static int need_color_reset_at_eol; -static void color_atom_parser(struct used_atom *atom, const char *color_value) +static void color_atom_parser(const struct ref_format *format, struct used_atom *atom, const char *color_value) { if (!color_value) die(_("expected format: %%(color:<color>)")); if (color_parse(color_value, atom->u.color) < 0) die(_("unrecognized color: %%(color:%s)"), color_value); + /* + * We check this after we've parsed the color, which lets us complain + * about syntactically bogus color names even if they won't be used. + */ + if (!want_color(format->use_color)) + color_parse("", atom->u.color); } static void refname_atom_parser_internal(struct refname_atom *atom, @@ -127,7 +132,7 @@ static void refname_atom_parser_internal(struct refname_atom *atom, die(_("unrecognized %%(%s) argument: %s"), name, arg); } -static void remote_ref_atom_parser(struct used_atom *atom, const char *arg) +static void remote_ref_atom_parser(const struct ref_format *format, struct used_atom *atom, const char *arg) { struct string_list params = STRING_LIST_INIT_DUP; int i; @@ -161,28 +166,28 @@ static void remote_ref_atom_parser(struct used_atom *atom, const char *arg) string_list_clear(¶ms, 0); } -static void body_atom_parser(struct used_atom *atom, const char *arg) +static void body_atom_parser(const struct ref_format *format, struct used_atom *atom, const char *arg) { if (arg) die(_("%%(body) does not take arguments")); atom->u.contents.option = C_BODY_DEP; } -static void subject_atom_parser(struct used_atom *atom, const char *arg) +static void subject_atom_parser(const struct ref_format *format, struct used_atom *atom, const char *arg) { if (arg) die(_("%%(subject) does not take arguments")); atom->u.contents.option = C_SUB; } -static void trailers_atom_parser(struct used_atom *atom, const char *arg) +static void trailers_atom_parser(const struct ref_format *format, struct used_atom *atom, const char *arg) { if (arg) die(_("%%(trailers) does not take arguments")); atom->u.contents.option = C_TRAILERS; } -static void contents_atom_parser(struct used_atom *atom, const char *arg) +static void contents_atom_parser(const struct ref_format *format, struct used_atom *atom, const char *arg) { if (!arg) atom->u.contents.option = C_BARE; @@ -202,7 +207,7 @@ static void contents_atom_parser(struct used_atom *atom, const char *arg) die(_("unrecognized %%(contents) argument: %s"), arg); } -static void objectname_atom_parser(struct used_atom *atom, const char *arg) +static void objectname_atom_parser(const struct ref_format *format, struct used_atom *atom, const char *arg) { if (!arg) atom->u.objectname.option = O_FULL; @@ -219,7 +224,7 @@ static void objectname_atom_parser(struct used_atom *atom, const char *arg) die(_("unrecognized %%(objectname) argument: %s"), arg); } -static void refname_atom_parser(struct used_atom *atom, const char *arg) +static void refname_atom_parser(const struct ref_format *format, struct used_atom *atom, const char *arg) { refname_atom_parser_internal(&atom->u.refname, arg, atom->name); } @@ -235,7 +240,7 @@ static align_type parse_align_position(const char *s) return -1; } -static void align_atom_parser(struct used_atom *atom, const char *arg) +static void align_atom_parser(const struct ref_format *format, struct used_atom *atom, const char *arg) { struct align *align = &atom->u.align; struct string_list params = STRING_LIST_INIT_DUP; @@ -274,7 +279,7 @@ static void align_atom_parser(struct used_atom *atom, const char *arg) string_list_clear(¶ms, 0); } -static void if_atom_parser(struct used_atom *atom, const char *arg) +static void if_atom_parser(const struct ref_format *format, struct used_atom *atom, const char *arg) { if (!arg) { atom->u.if_then_else.cmp_status = COMPARE_NONE; @@ -288,7 +293,7 @@ static void if_atom_parser(struct used_atom *atom, const char *arg) } } -static void head_atom_parser(struct used_atom *atom, const char *arg) +static void head_atom_parser(const struct ref_format *format, struct used_atom *atom, const char *arg) { struct object_id unused; @@ -298,7 +303,7 @@ static void head_atom_parser(struct used_atom *atom, const char *arg) static struct { const char *name; cmp_type cmp_type; - void (*parser)(struct used_atom *atom, const char *arg); + void (*parser)(const struct ref_format *format, struct used_atom *atom, const char *arg); } valid_atom[] = { { "refname" , FIELD_STR, refname_atom_parser }, { "objecttype" }, @@ -365,7 +370,8 @@ struct atom_value { /* * Used to parse format string and sort specifiers */ -int parse_ref_filter_atom(const char *atom, const char *ep) +static int parse_ref_filter_atom(const struct ref_format *format, + const char *atom, const char *ep) { const char *sp; const char *arg; @@ -413,7 +419,7 @@ int parse_ref_filter_atom(const char *atom, const char *ep) arg = used_atom[at].name + (arg - atom) + 1; memset(&used_atom[at].u, 0, sizeof(used_atom[at].u)); if (valid_atom[i].parser) - valid_atom[i].parser(&used_atom[at], arg); + valid_atom[i].parser(format, &used_atom[at], arg); if (*atom == '*') need_tagged = 1; if (!strcmp(valid_atom[i].name, "symref")) @@ -657,24 +663,26 @@ static const char *find_next(const char *cp) * Make sure the format string is well formed, and parse out * the used atoms. */ -int verify_ref_format(const char *format) +int verify_ref_format(struct ref_format *format) { const char *cp, *sp; - need_color_reset_at_eol = 0; - for (cp = format; *cp && (sp = find_next(cp)); ) { + format->need_color_reset_at_eol = 0; + for (cp = format->format; *cp && (sp = find_next(cp)); ) { const char *color, *ep = strchr(sp, ')'); int at; if (!ep) return error(_("malformed format string %s"), sp); /* sp points at "%(" and ep points at the closing ")" */ - at = parse_ref_filter_atom(sp + 2, ep); + at = parse_ref_filter_atom(format, sp + 2, ep); cp = ep + 1; if (skip_prefix(used_atom[at].name, "color:", &color)) - need_color_reset_at_eol = !!strcmp(color, "reset"); + format->need_color_reset_at_eol = !!strcmp(color, "reset"); } + if (format->need_color_reset_at_eol && !want_color(format->use_color)) + format->need_color_reset_at_eol = 0; return 0; } @@ -2060,35 +2068,34 @@ static void append_literal(const char *cp, const char *ep, struct ref_formatting } } -void format_ref_array_item(struct ref_array_item *info, const char *format, - int quote_style, struct strbuf *final_buf) +void format_ref_array_item(struct ref_array_item *info, + const struct ref_format *format, + struct strbuf *final_buf) { const char *cp, *sp, *ep; struct ref_formatting_state state = REF_FORMATTING_STATE_INIT; - state.quote_style = quote_style; + state.quote_style = format->quote_style; push_stack_element(&state.stack); - for (cp = format; *cp && (sp = find_next(cp)); cp = ep + 1) { + for (cp = format->format; *cp && (sp = find_next(cp)); cp = ep + 1) { struct atom_value *atomv; ep = strchr(sp, ')'); if (cp < sp) append_literal(cp, sp, &state); - get_ref_atom_value(info, parse_ref_filter_atom(sp + 2, ep), &atomv); + get_ref_atom_value(info, + parse_ref_filter_atom(format, sp + 2, ep), + &atomv); atomv->handler(atomv, &state); } if (*cp) { sp = cp + strlen(cp); append_literal(cp, sp, &state); } - if (need_color_reset_at_eol) { + if (format->need_color_reset_at_eol) { struct atom_value resetv; - char color[COLOR_MAXLEN] = ""; - - if (color_parse("reset", color) < 0) - die("BUG: couldn't parse 'reset' as a color"); - resetv.s = color; + resetv.s = GIT_COLOR_RESET; append_atom(&resetv, &state); } if (state.stack->prev) @@ -2097,26 +2104,38 @@ void format_ref_array_item(struct ref_array_item *info, const char *format, pop_stack_element(&state.stack); } -void show_ref_array_item(struct ref_array_item *info, const char *format, int quote_style) +void show_ref_array_item(struct ref_array_item *info, + const struct ref_format *format) { struct strbuf final_buf = STRBUF_INIT; - format_ref_array_item(info, format, quote_style, &final_buf); + format_ref_array_item(info, format, &final_buf); fwrite(final_buf.buf, 1, final_buf.len, stdout); strbuf_release(&final_buf); putchar('\n'); } void pretty_print_ref(const char *name, const unsigned char *sha1, - const char *format) + const struct ref_format *format) { struct ref_array_item *ref_item; ref_item = new_ref_array_item(name, sha1, 0); ref_item->kind = ref_kind_from_refname(name); - show_ref_array_item(ref_item, format, 0); + show_ref_array_item(ref_item, format); free_array_item(ref_item); } +static int parse_sorting_atom(const char *atom) +{ + /* + * This parses an atom using a dummy ref_format, since we don't + * actually care about the formatting details. + */ + struct ref_format dummy = REF_FORMAT_INIT; + const char *end = atom + strlen(atom); + return parse_ref_filter_atom(&dummy, atom, end); +} + /* If no sorting option is given, use refname to sort as default */ struct ref_sorting *ref_default_sorting(void) { @@ -2125,18 +2144,13 @@ struct ref_sorting *ref_default_sorting(void) struct ref_sorting *sorting = xcalloc(1, sizeof(*sorting)); sorting->next = NULL; - sorting->atom = parse_ref_filter_atom(cstr_name, cstr_name + strlen(cstr_name)); + sorting->atom = parse_sorting_atom(cstr_name); return sorting; } -int parse_opt_ref_sorting(const struct option *opt, const char *arg, int unset) +void parse_ref_sorting(struct ref_sorting **sorting_tail, const char *arg) { - struct ref_sorting **sorting_tail = opt->value; struct ref_sorting *s; - int len; - - if (!arg) /* should --no-sort void the list ? */ - return -1; s = xcalloc(1, sizeof(*s)); s->next = *sorting_tail; @@ -2149,8 +2163,14 @@ int parse_opt_ref_sorting(const struct option *opt, const char *arg, int unset) if (skip_prefix(arg, "version:", &arg) || skip_prefix(arg, "v:", &arg)) s->version = 1; - len = strlen(arg); - s->atom = parse_ref_filter_atom(arg, arg+len); + s->atom = parse_sorting_atom(arg); +} + +int parse_opt_ref_sorting(const struct option *opt, const char *arg, int unset) +{ + if (!arg) /* should --no-sort void the list ? */ + return -1; + parse_ref_sorting(opt->value, arg); return 0; } |