diff mbox series

[v2,4/7] quote_path: code clarification

Message ID 20200910170159.1278781-5-gitster@pobox.com
State New
Headers show
Series quote_path() clean-ups | expand

Commit Message

Junio C Hamano Sept. 10, 2020, 5:01 p.m. UTC
The implementation we moved from wt-status to enclose a pathname
that has a SP in it inside a dq-pair is a bit convoluted.  It lets
quote_c_style_counted() do its escaping and then

 (1) if the input string got escaped, which is checked by seeing if
     the result begins with a double-quote, declare that we are
     done.  If there wasn't any SP in the input, that is OK, and if
     there was, the result is quoted already so it is OK, too.

 (2) if the input string did not get escaped, and the result has SP
     in it, enclose the whole thing in a dq-pair ourselves.

Instead we can scan the path upfront to see if the input has SP in
it.  If so, we tell quote_c_style_counted() not to enclose its
output in a dq-pair, and we add a dq-pair ourselves.  Whether the
input had bytes that quote_c_style_counted() uses backslash quoting,
this would give us a desired quoted string.  If the input does not
have SP in it, we just let quote_c_style_counted() do its thing as
usual, which would enclose the result in a dq-pair only when needed.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
 quote.c | 19 ++++++++++++-------
 1 file changed, 12 insertions(+), 7 deletions(-)

Comments

Jeff King Sept. 10, 2020, 6:08 p.m. UTC | #1
On Thu, Sep 10, 2020 at 10:01:56AM -0700, Junio C Hamano wrote:

> Instead we can scan the path upfront to see if the input has SP in
> it.  If so, we tell quote_c_style_counted() not to enclose its
> output in a dq-pair, and we add a dq-pair ourselves.  Whether the
> input had bytes that quote_c_style_counted() uses backslash quoting,
> this would give us a desired quoted string.  If the input does not
> have SP in it, we just let quote_c_style_counted() do its thing as
> usual, which would enclose the result in a dq-pair only when needed.

Nice. I think the result is easier to follow than the original, not to
mention more efficient. And the fact that we didn't need to touch
quote_c_style_counted() is the cherry on top.

> +	int force_dq = ((flags & QUOTE_PATH_QUOTE_SP) && strchr(rel, ' '));
> [...]
> +	quote_c_style_counted(rel, strlen(rel), out, NULL, !!force_dq);

I think force_dq is already normalized to 0/1 by the &&, so we wouldn't
need the "!!" here.

-Peff
Junio C Hamano Sept. 10, 2020, 6:40 p.m. UTC | #2
Jeff King <peff@peff.net> writes:

> On Thu, Sep 10, 2020 at 10:01:56AM -0700, Junio C Hamano wrote:
>
>> Instead we can scan the path upfront to see if the input has SP in
>> it.  If so, we tell quote_c_style_counted() not to enclose its
>> output in a dq-pair, and we add a dq-pair ourselves.  Whether the
>> input had bytes that quote_c_style_counted() uses backslash quoting,
>> this would give us a desired quoted string.  If the input does not
>> have SP in it, we just let quote_c_style_counted() do its thing as
>> usual, which would enclose the result in a dq-pair only when needed.
>
> Nice. I think the result is easier to follow than the original, not to
> mention more efficient. And the fact that we didn't need to touch
> quote_c_style_counted() is the cherry on top.
>
>> +	int force_dq = ((flags & QUOTE_PATH_QUOTE_SP) && strchr(rel, ' '));
>> [...]
>> +	quote_c_style_counted(rel, strlen(rel), out, NULL, !!force_dq);
>
> I think force_dq is already normalized to 0/1 by the &&, so we wouldn't
> need the "!!" here.

True.  CQUOTE_NODQ patch would get rid of it in the end, though ;-)
Jeff King Sept. 10, 2020, 7:29 p.m. UTC | #3
On Thu, Sep 10, 2020 at 11:40:42AM -0700, Junio C Hamano wrote:

> >> +	int force_dq = ((flags & QUOTE_PATH_QUOTE_SP) && strchr(rel, ' '));
> >> [...]
> >> +	quote_c_style_counted(rel, strlen(rel), out, NULL, !!force_dq);
> >
> > I think force_dq is already normalized to 0/1 by the &&, so we wouldn't
> > need the "!!" here.
> 
> True.  CQUOTE_NODQ patch would get rid of it in the end, though ;-)

Oh, true. I didn't think to look ahead. Having done so, yeah, I don't
see any point in quibbling about this one. :)

-Peff
diff mbox series

Patch

diff --git a/quote.c b/quote.c
index aa9a37b1b1..b8107cd403 100644
--- a/quote.c
+++ b/quote.c
@@ -356,16 +356,21 @@  char *quote_path(const char *in, const char *prefix, struct strbuf *out, unsigne
 {
 	struct strbuf sb = STRBUF_INIT;
 	const char *rel = relative_path(in, prefix, &sb);
+	int force_dq = ((flags & QUOTE_PATH_QUOTE_SP) && strchr(rel, ' '));
+
 	strbuf_reset(out);
-	quote_c_style_counted(rel, strlen(rel), out, NULL, 0);
-	strbuf_release(&sb);
 
-	if ((flags & QUOTE_PATH_QUOTE_SP) &&
-	    (out->buf[0] != '"' && strchr(out->buf, ' '))) {
-		/* Ensure the whole thing is quoted if the path has SP in it */
-		strbuf_insertstr(out, 0, "\"");
+	/*
+	 * If the caller wants us to enclose the output in a dq-pair
+	 * whether quote_c_style_counted() needs to, we do it ourselves
+	 * and tell quote_c_style_counted() not to.
+	 */
+	if (force_dq)
 		strbuf_addch(out, '"');
-	}
+	quote_c_style_counted(rel, strlen(rel), out, NULL, !!force_dq);
+	if (force_dq)
+		strbuf_addch(out, '"');
+	strbuf_release(&sb);
 
 	return out->buf;
 }