This breaks t4034 (word diffs), but all other tests pass.

emit_line_0 grew complicated again, so here is an attempt to make it
a bit simpler. emit_line_0 is called for all lines that are added,
removed or context lines, and it follows the format:

 <sign color> <sign> <main color> <content of length 'len'> <reset> <CR> <LF>

with each of the components optional. However a few rules apply:
* The CR/LF is passed to the function as part of line/len, so we have
  to figure out if we need to separate them
* As the sign color is a rather recent addition, we do not optimize it
  yet
* the main color insertion is new, as the color used to be inserted before
  the sign
* another follow up cleanup (that also touches the tests) could be
  a stricter check to consolidate with ws_check_emit (and not emit the
  color/reset twice)

Signed-off-by: Stefan Beller <sbel...@google.com>
---
 diff.c | 78 ++++++++++++++++++++++++++++------------------------------
 1 file changed, 37 insertions(+), 41 deletions(-)

diff --git a/diff.c b/diff.c
index 028d7d9a59c..7b649f57c27 100644
--- a/diff.c
+++ b/diff.c
@@ -563,44 +563,44 @@ static void check_blank_at_eof(mmfile_t *mf1, mmfile_t 
*mf2,
 }
 
 static void emit_line_0(struct diff_options *o,
-                       const char *set, unsigned reverse, const char *reset,
-                       int first, const char *line, int len)
+                       const char *maincolor, const char *signcolor,
+                       const char *reset, const char *sign,
+                       const char *line, int len)
 {
        int has_trailing_newline, has_trailing_carriage_return;
-       int nofirst;
        FILE *file = o->file;
 
-       if (first)
-               fputs(diff_line_prefix(o), file);
-       else if (!len)
-               return;
+       fputs(diff_line_prefix(o), file);
 
-       if (len == 0) {
-               has_trailing_newline = (first == '\n');
-               has_trailing_carriage_return = (!has_trailing_newline &&
-                                               (first == '\r'));
-               nofirst = has_trailing_newline || has_trailing_carriage_return;
-       } else {
-               has_trailing_newline = (len > 0 && line[len-1] == '\n');
-               if (has_trailing_newline)
-                       len--;
-               has_trailing_carriage_return = (len > 0 && line[len-1] == '\r');
-               if (has_trailing_carriage_return)
-                       len--;
-               nofirst = 0;
-       }
+       has_trailing_newline = (len > 0 && line[len-1] == '\n');
+       if (has_trailing_newline)
+               len--;
+       has_trailing_carriage_return = (len > 0 && line[len-1] == '\r');
+       if (has_trailing_carriage_return)
+               len--;
 
-       if (len || !nofirst) {
-               if (reverse && want_color(o->use_color))
-                       fputs(GIT_COLOR_REVERSE, file);
-               fputs(set, file);
-               if (first && !nofirst)
-                       fputc(first, file);
+       if (signcolor)
+               fputs(signcolor, file);
+       else if (maincolor)
+               fputs(maincolor, file);
+
+
+       if (sign)
+               fputs(sign, file);
+
+       /* only put main color here if it we did not color the sign the same 
way */
+       if (signcolor && maincolor && signcolor != maincolor)
+               fputs(maincolor, file);
+
+       if (len)
                fwrite(line, len, 1, file);
+
+       if ((signcolor || maincolor) && reset)
                fputs(reset, file);
-       }
+
        if (has_trailing_carriage_return)
                fputc('\r', file);
+
        if (has_trailing_newline)
                fputc('\n', file);
 }
@@ -608,7 +608,7 @@ static void emit_line_0(struct diff_options *o,
 static void emit_line(struct diff_options *o, const char *set, const char 
*reset,
                      const char *line, int len)
 {
-       emit_line_0(o, set, 0, reset, line[0], line+1, len-1);
+       emit_line_0(o, set, NULL, reset, NULL, line, len);
 }
 
 enum diff_symbol {
@@ -980,20 +980,16 @@ static void emit_line_ws_markup(struct diff_options *o,
                        ws = NULL;
        }
 
-       if (!ws && !set_sign)
-               emit_line_0(o, set, 0, reset, sign[0], line, len);
-       else if (!ws) {
-               /* Emit just the prefix, then the rest. */
-               emit_line_0(o, set_sign ? set_sign : set, !!set_sign, reset,
-                           sign[0], "", 0);
-               emit_line_0(o, set, 0, reset, 0, line, len);
-       } else if (blank_at_eof)
+       if (!ws)
+               emit_line_0(o, set, set_sign, reset,
+                           sign, line, len);
+       else if (blank_at_eof)
                /* Blank line at EOF - paint '+' as well */
-               emit_line_0(o, ws, 0, reset, sign[0], line, len);
+               emit_line_0(o, ws, set_sign, reset, sign, line, len);
        else {
                /* Emit just the prefix, then the rest. */
-               emit_line_0(o, set_sign ? set_sign : set, !!set_sign, reset,
-                           sign[0], "", 0);
+               emit_line_0(o, set, set_sign, reset,
+                           sign, "", 0);
                ws_check_emit(line, len, ws_rule,
                              o->file, set, reset, ws);
        }
@@ -1016,7 +1012,7 @@ static void emit_diff_symbol_from_struct(struct 
diff_options *o,
                context = diff_get_color_opt(o, DIFF_CONTEXT);
                reset = diff_get_color_opt(o, DIFF_RESET);
                putc('\n', o->file);
-               emit_line_0(o, context, 0, reset, '\\',
+               emit_line_0(o, context, 0, reset, "\\",
                            nneof, strlen(nneof));
                break;
        case DIFF_SYMBOL_SUBMODULE_HEADER:
-- 
2.18.0.203.gfac676dfb9-goog

Reply via email to