} *used_atom;
static int used_atom_cnt, need_tagged, need_symref;
-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,
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;
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;
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;
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);
}
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;
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;
}
}
-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;
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" },
/*
* Used to parse format string and sort specifiers
*/
-static 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;
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"))
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))
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;
}
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) {
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)
{
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;
}
void parse_ref_sorting(struct ref_sorting **sorting_tail, const char *arg)
{
struct ref_sorting *s;
- int len;
s = xcalloc(1, sizeof(*s));
s->next = *sorting_tail;
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)