Re: [PATCH] diff --color-words -U0: fix the location of hunk headers

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Markus Heidelberg <markus.heidelberg@xxxxxx> writes:

> I try to reword:
> With 2/3 and 3/3 I wanted to keep --color-words specific code in the
> block starting with
>
> 	if (ecbdata->diff_words) {
>
> and didn't want to contaminate the block starting with
>
> 	if (line[0] == '@') {
>
> with non-hunk-header content.

The contamination was already done long time ago.  The way "color words"
mode piggybacks into the rest of the code is to let the line oriented diff
codepath run, capture the lines to its buffer so that it can split them
into words and compare, and hijack the control flow not to let the line
oriented diff to be output, and in the context of the original design,
Dscho's patch makes sense.

I do think that the way the "color words" logic has to touch line-oriented
codepaths unnecessarily makes it look intrusive; one reason is because it
exposes the state that is only interesting to the "color words" mode to
these places too much.

With a small helper function on top of Dscho's patch, I think the code can
be made a lot more readable.  This way, "consume" codepath is made more
about "here is what we do when we get a line from the line-oriented diff
engine", and we can keep the knowledge of "color words" mode to the
minimum (no more than "here is where we may need to flush the buffer").
The helper hides the implementation details such as how we decide if we
have accumulated words or what we do when we do need to flush.

There is another large-ish "if (ecbdata->diff_words)" codeblock in
fn_out_consume() that peeks into *(ecbdata->diff_words); I think it should
be ejected from the main codepath for the same reason (i.e. readability).
.
Probably we can make a helper function that has only a single caller, like
this:

        static void diff_words_use_line(char *line, unsigned long len,
                                        struct emit_callback *ecbdata,
                                        const char *plain, const char *reset)
        {
                if (line[0] == '-') {
                        diff_words_append(line, len,
                                          &ecbdata->diff_words->minus);
                        return;
                } else if (line[0] == '+') {
                        diff_words_append(line, len,
                                          &ecbdata->diff_words->plus);
                        return;
                }
                diff_words_flush(ecbdata);
                line++;
                len--;
                emit_line(ecbdata->file, plain, reset, line, len);
        }

It would even be cleaner to change "diff_words_append()" function to do
all of the above.

But that is outside the scope of this comment.


 diff.c |   26 ++++++++++++--------------
 1 files changed, 12 insertions(+), 14 deletions(-)

diff --git a/diff.c b/diff.c
index b7ecfe3..8c66e4a 100644
--- a/diff.c
+++ b/diff.c
@@ -541,14 +541,18 @@ struct emit_callback {
 	FILE *file;
 };
 
+/* In "color-words" mode, show word-diff of words accumulated in the buffer */
+static void diff_words_flush(struct emit_callback *ecbdata)
+{
+	if (ecbdata->diff_words->minus.text.size ||
+	    ecbdata->diff_words->plus.text.size)
+		diff_words_show(ecbdata->diff_words);
+}
+
 static void free_diff_words_data(struct emit_callback *ecbdata)
 {
 	if (ecbdata->diff_words) {
-		/* flush buffers */
-		if (ecbdata->diff_words->minus.text.size ||
-				ecbdata->diff_words->plus.text.size)
-			diff_words_show(ecbdata->diff_words);
-
+		diff_words_flush(ecbdata);
 		free (ecbdata->diff_words->minus.text.ptr);
 		free (ecbdata->diff_words->minus.orig);
 		free (ecbdata->diff_words->plus.text.ptr);
@@ -656,12 +660,8 @@ static void fn_out_consume(void *priv, char *line, unsigned long len)
 	for (i = 0; i < len && line[i] == '@'; i++)
 		;
 	if (2 <= i && i < len && line[i] == ' ') {
-		/* flush --color-words even for --unified=0 */
-		if (ecbdata->diff_words &&
-		    (ecbdata->diff_words->minus.text.size ||
-		     ecbdata->diff_words->plus.text.size))
-			diff_words_show(ecbdata->diff_words);
-
+		if (ecbdata->diff_words)
+			diff_words_flush(ecbdata);
 		ecbdata->nparents = i - 1;
 		len = sane_truncate_line(ecbdata, line, len);
 		emit_line(ecbdata->file,
@@ -691,9 +691,7 @@ static void fn_out_consume(void *priv, char *line, unsigned long len)
 					  &ecbdata->diff_words->plus);
 			return;
 		}
-		if (ecbdata->diff_words->minus.text.size ||
-		    ecbdata->diff_words->plus.text.size)
-			diff_words_show(ecbdata->diff_words);
+		diff_words_flush(ecbdata);
 		line++;
 		len--;
 		emit_line(ecbdata->file, plain, reset, line, len);
--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Linux Kernel Development]     [Gcc Help]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [V4L]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Fedora Users]