git@vger.kernel.org mailing list mirror (one of many)
 help / color / mirror / code / Atom feed
From: Jeff King <peff@peff.net>
To: git@vger.kernel.org
Subject: [PATCH 10/15] ref-filter: pass ref_format struct to atom parsers
Date: Thu, 13 Jul 2017 11:06:40 -0400	[thread overview]
Message-ID: <20170713150640.qnefucyb4buggo6q@sigill.intra.peff.net> (raw)
In-Reply-To: <20170713145553.3epnsw23zajwg3ee@sigill.intra.peff.net>

The callback for parsing each formatting atom gets to see
only the atom struct (which it's filling in) and the text to
be parsed. This doesn't leave any room for it to behave
differently based on context known only to the ref_format.

We can solve this by passing in the surrounding ref_format
to each parser. Note that this makes things slightly awkward
for sort strings, which parse atoms without having a
ref_format. We'll solve that by using a dummy ref_format
with default parameters.

Signed-off-by: Jeff King <peff@peff.net>
---
If we eventually do move used_atoms into the format, we'd probably need
to either have a separate ref_format for the sorting atoms, or have them
share with the struct used for actual formatting. At this point I don't
think it matters at all. You can do nonsense like:

  git for-each-ref --sort='%(color:red)'

and after this series it will not respect your color.ui setting. But
since in either case it's a ridiculous sort key (whether it shows the
color or not, it's the same for all refs and so can't affect the
sorting), it's not worth caring about.

If we do eventually refactor ref_format more such that the dummy struct
doesn't cut it, I think we can deal with the issue then.

 ref-filter.c | 42 +++++++++++++++++++++++++-----------------
 1 file changed, 25 insertions(+), 17 deletions(-)

diff --git a/ref-filter.c b/ref-filter.c
index 080f5aceb..129a63677 100644
--- a/ref-filter.c
+++ b/ref-filter.c
@@ -98,7 +98,7 @@ static struct used_atom {
 } *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>)"));
@@ -126,7 +126,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;
@@ -160,28 +160,28 @@ static void remote_ref_atom_parser(struct used_atom *atom, const char *arg)
 	string_list_clear(&params, 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;
@@ -201,7 +201,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;
@@ -218,7 +218,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);
 }
@@ -234,7 +234,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;
@@ -273,7 +273,7 @@ static void align_atom_parser(struct used_atom *atom, const char *arg)
 	string_list_clear(&params, 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;
@@ -287,7 +287,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;
 
@@ -297,7 +297,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" },
@@ -364,7 +364,8 @@ struct atom_value {
 /*
  * 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;
@@ -412,7 +413,7 @@ static 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"))
@@ -668,7 +669,7 @@ int verify_ref_format(struct ref_format *format)
 		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))
@@ -2075,7 +2076,9 @@ void format_ref_array_item(struct ref_array_item *info,
 		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) {
@@ -2116,8 +2119,13 @@ void pretty_print_ref(const char *name, const unsigned char *sha1,
 
 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(atom, end);
+	return parse_ref_filter_atom(&dummy, atom, end);
 }
 
 /*  If no sorting option is given, use refname to sort as default */
-- 
2.13.2.1157.gc6daca446


  parent reply	other threads:[~2017-07-13 15:07 UTC|newest]

Thread overview: 30+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-07-13 14:55 [PATCH 0/15] making user-format colors conditional on config/tty Jeff King
2017-07-13 14:56 ` [PATCH 01/15] check return value of verify_ref_format() Jeff King
2017-07-13 14:56 ` [PATCH 02/15] docs/for-each-ref: update pointer to color syntax Jeff King
2017-07-13 20:15   ` Junio C Hamano
2017-07-13 14:58 ` [PATCH 03/15] t: use test_decode_color rather than literal ANSI codes Jeff King
2017-07-13 18:40   ` Stefan Beller
2017-07-13 18:45     ` Jeff King
2017-07-13 19:27       ` Junio C Hamano
2017-07-14 11:50         ` Jeff King
2017-07-13 20:18   ` Junio C Hamano
2017-07-13 14:58 ` [PATCH 04/15] ref-filter: simplify automatic color reset Jeff King
2017-07-13 15:01 ` [PATCH 05/15] ref-filter: abstract ref format into its own struct Jeff King
2017-07-13 18:51   ` Stefan Beller
2017-07-13 20:34     ` Junio C Hamano
2017-07-13 21:32       ` Junio C Hamano
2017-07-13 22:01         ` Stefan Beller
2017-07-13 22:45           ` Junio C Hamano
2017-07-13 15:02 ` [PATCH 06/15] ref-filter: move need_color_reset_at_eol into ref_format Jeff King
2017-07-13 20:36   ` Junio C Hamano
2017-07-13 15:02 ` [PATCH 07/15] ref-filter: provide a function for parsing sort options Jeff King
2017-07-13 15:02 ` [PATCH 08/15] ref-filter: make parse_ref_filter_atom a private function Jeff King
2017-07-13 15:02 ` [PATCH 09/15] ref-filter: factor out the parsing of sorting atoms Jeff King
2017-07-13 15:06 ` Jeff King [this message]
2017-07-13 15:07 ` [PATCH 11/15] color: check color.ui in git_default_config() Jeff King
2017-07-13 15:07 ` [PATCH 12/15] for-each-ref: load config earlier Jeff King
2017-07-13 15:07 ` [PATCH 13/15] rev-list: pass diffopt->use_colors through to pretty-print Jeff King
2017-07-13 15:08 ` [PATCH 14/15] pretty: respect color settings for %C placeholders Jeff King
2017-07-13 15:09 ` [PATCH 15/15] ref-filter: consult want_color() before emitting colors Jeff King
2017-07-13 19:14 ` [PATCH 0/15] making user-format colors conditional on config/tty Stefan Beller
2017-07-13 20:46 ` Junio C Hamano

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: http://vger.kernel.org/majordomo-info.html

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20170713150640.qnefucyb4buggo6q@sigill.intra.peff.net \
    --to=peff@peff.net \
    --cc=git@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://80x24.org/mirrors/git.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).