From 84120cca09002453649abf40e1873c4041247d64 Mon Sep 17 00:00:00 2001 From: Stefan Beller Date: Mon, 13 Aug 2018 18:41:17 -0700 Subject: diff.c: simplify caller of emit_line_0 Due to the previous condition we know "set_sign != NULL" at that point. Signed-off-by: Stefan Beller Signed-off-by: Junio C Hamano --- diff.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'diff.c') diff --git a/diff.c b/diff.c index ae13149521..f6df18af91 100644 --- a/diff.c +++ b/diff.c @@ -1202,8 +1202,7 @@ static void emit_line_ws_markup(struct diff_options *o, emit_line_0(o, set, 0, reset, sign, 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); + emit_line_0(o, set_sign, !!set_sign, reset, sign, "", 0); emit_line_0(o, set, 0, reset, 0, line, len); } else if (blank_at_eof) /* Blank line at EOF - paint '+' as well */ -- cgit v1.2.3 From 9d1e16bf59cd35e1019e63b171ddf9209e0f53a1 Mon Sep 17 00:00:00 2001 From: Stefan Beller Date: Mon, 13 Aug 2018 18:41:18 -0700 Subject: diff.c: reorder arguments for emit_line_ws_markup The order shall be all colors first, then the content, flags at the end. The colors are in the order of occurrence, i.e. first the color for the sign and then the color for the rest of the line. Signed-off-by: Stefan Beller Signed-off-by: Junio C Hamano --- diff.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'diff.c') diff --git a/diff.c b/diff.c index f6df18af91..ab6e6a88a5 100644 --- a/diff.c +++ b/diff.c @@ -1185,9 +1185,9 @@ static void dim_moved_lines(struct diff_options *o) } static void emit_line_ws_markup(struct diff_options *o, - const char *set, const char *reset, - const char *line, int len, - const char *set_sign, char sign, + const char *set_sign, const char *set, + const char *reset, + char sign, const char *line, int len, unsigned ws_rule, int blank_at_eof) { const char *ws = NULL; @@ -1271,7 +1271,7 @@ static void emit_diff_symbol_from_struct(struct diff_options *o, else if (c == '-') set = diff_get_color_opt(o, DIFF_FILE_OLD); } - emit_line_ws_markup(o, set, reset, line, len, set_sign, ' ', + emit_line_ws_markup(o, set_sign, set, reset, ' ', line, len, flags & (DIFF_SYMBOL_CONTENT_WS_MASK), 0); break; case DIFF_SYMBOL_PLUS: @@ -1314,7 +1314,7 @@ static void emit_diff_symbol_from_struct(struct diff_options *o, set = diff_get_color_opt(o, DIFF_CONTEXT_BOLD); flags &= ~DIFF_SYMBOL_CONTENT_WS_MASK; } - emit_line_ws_markup(o, set, reset, line, len, set_sign, '+', + emit_line_ws_markup(o, set_sign, set, reset, '+', line, len, flags & DIFF_SYMBOL_CONTENT_WS_MASK, flags & DIFF_SYMBOL_CONTENT_BLANK_LINE_EOF); break; @@ -1357,7 +1357,7 @@ static void emit_diff_symbol_from_struct(struct diff_options *o, else set = diff_get_color_opt(o, DIFF_CONTEXT_DIM); } - emit_line_ws_markup(o, set, reset, line, len, set_sign, '-', + emit_line_ws_markup(o, set_sign, set, reset, '-', line, len, flags & DIFF_SYMBOL_CONTENT_WS_MASK, 0); break; case DIFF_SYMBOL_WORDS_PORCELAIN: -- cgit v1.2.3 From 017ac45e87074a51e7bf926b8f87152a1af9a441 Mon Sep 17 00:00:00 2001 From: Stefan Beller Date: Mon, 13 Aug 2018 18:41:19 -0700 Subject: diff.c: add set_sign to emit_line_0 Split the meaning of the `set` parameter that is passed to emit_line_0()` to separate between the color of the "sign" (i.e. the diff marker '+', '-' or ' ' that is passed in as the `first` parameter) and the color of the rest of the line. This changes the meaning of the `set` parameter to no longer refer to the color of the diff marker, but instead to refer to the color of the rest of the line. A value of `NULL` indicates that the rest of the line wants to be colored the same as the diff marker. Helped-by: Johannes Schindelin Signed-off-by: Stefan Beller Signed-off-by: Junio C Hamano --- diff.c | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) (limited to 'diff.c') diff --git a/diff.c b/diff.c index ab6e6a88a5..4ef6638928 100644 --- a/diff.c +++ b/diff.c @@ -622,7 +622,7 @@ 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, + const char *set_sign, const char *set, unsigned reverse, const char *reset, int first, const char *line, int len) { int has_trailing_newline, has_trailing_carriage_return; @@ -652,9 +652,15 @@ static void emit_line_0(struct diff_options *o, if (len || !nofirst) { if (reverse && want_color(o->use_color)) fputs(GIT_COLOR_REVERSE, file); - fputs(set, file); + if (set_sign) + fputs(set_sign, file); if (first && !nofirst) fputc(first, file); + if (set && set != set_sign) { + if (set_sign) + fputs(reset, file); + fputs(set, file); + } fwrite(line, len, 1, file); fputs(reset, file); } @@ -667,7 +673,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, 0, reset, line[0], line+1, len-1); } enum diff_symbol { @@ -1199,17 +1205,17 @@ static void emit_line_ws_markup(struct diff_options *o, } if (!ws && !set_sign) - emit_line_0(o, set, 0, reset, sign, line, len); + emit_line_0(o, set, NULL, 0, reset, sign, line, len); else if (!ws) { /* Emit just the prefix, then the rest. */ - emit_line_0(o, set_sign, !!set_sign, reset, sign, "", 0); - emit_line_0(o, set, 0, reset, 0, line, len); + emit_line_0(o, set_sign, NULL, !!set_sign, reset, sign, "", 0); + emit_line_0(o, set, NULL, 0, reset, 0, line, len); } else if (blank_at_eof) /* Blank line at EOF - paint '+' as well */ - emit_line_0(o, ws, 0, reset, sign, line, len); + emit_line_0(o, ws, NULL, 0, reset, sign, line, len); else { /* Emit just the prefix, then the rest. */ - emit_line_0(o, set_sign ? set_sign : set, !!set_sign, reset, + emit_line_0(o, set_sign ? set_sign : set, NULL, !!set_sign, reset, sign, "", 0); ws_check_emit(line, len, ws_rule, o->file, set, reset, ws); @@ -1233,7 +1239,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, NULL, 0, reset, '\\', nneof, strlen(nneof)); break; case DIFF_SYMBOL_SUBMODULE_HEADER: -- cgit v1.2.3 From 29ef759d7ca039590240890a604be8308b30a069 Mon Sep 17 00:00:00 2001 From: Stefan Beller Date: Mon, 13 Aug 2018 18:41:20 -0700 Subject: diff: use emit_line_0 once per line All lines that use emit_line_0 multiple times per line, are combined into a single call to emit_line_0, making use of the 'set' argument. We gain a little efficiency here, as we can omit emission of color and accompanying reset if 'len == 0'. Signed-off-by: Stefan Beller Signed-off-by: Junio C Hamano --- diff.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'diff.c') diff --git a/diff.c b/diff.c index 4ef6638928..4f430f44e6 100644 --- a/diff.c +++ b/diff.c @@ -656,12 +656,14 @@ static void emit_line_0(struct diff_options *o, fputs(set_sign, file); if (first && !nofirst) fputc(first, file); - if (set && set != set_sign) { - if (set_sign) - fputs(reset, file); - fputs(set, file); + if (len) { + if (set && set != set_sign) { + if (set_sign) + fputs(reset, file); + fputs(set, file); + } + fwrite(line, len, 1, file); } - fwrite(line, len, 1, file); fputs(reset, file); } if (has_trailing_carriage_return) @@ -1207,9 +1209,7 @@ static void emit_line_ws_markup(struct diff_options *o, if (!ws && !set_sign) emit_line_0(o, set, NULL, 0, reset, sign, line, len); else if (!ws) { - /* Emit just the prefix, then the rest. */ - emit_line_0(o, set_sign, NULL, !!set_sign, reset, sign, "", 0); - emit_line_0(o, set, NULL, 0, reset, 0, line, len); + emit_line_0(o, set_sign, set, !!set_sign, reset, sign, line, len); } else if (blank_at_eof) /* Blank line at EOF - paint '+' as well */ emit_line_0(o, ws, NULL, 0, reset, sign, line, len); -- cgit v1.2.3 From f103a6faef97b062aa039d8e6c361340cfd8bc02 Mon Sep 17 00:00:00 2001 From: Stefan Beller Date: Mon, 13 Aug 2018 18:41:21 -0700 Subject: diff.c: omit check for line prefix in emit_line_0 As the previous patch made sure we only call emit_line_0 once per line, we do not need the work around introduced in f7c3b4e2d8c (diff: add an internal option to dual-color diffs of diffs, 2018-08-13) that would ensure we'd emit 'diff_line_prefix(o)' just once per line. By having just one call of emit_line_0 per line, the checks are dead code. Signed-off-by: Stefan Beller Signed-off-by: Junio C Hamano --- diff.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'diff.c') diff --git a/diff.c b/diff.c index 4f430f44e6..7a23adf254 100644 --- a/diff.c +++ b/diff.c @@ -629,10 +629,7 @@ static void emit_line_0(struct diff_options *o, 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'); -- cgit v1.2.3 From 444106791ee2c4c4575db439ef74d5db5ede6a27 Mon Sep 17 00:00:00 2001 From: Stefan Beller Date: Mon, 13 Aug 2018 18:41:22 -0700 Subject: diff.c: rewrite emit_line_0 more understandably Rewrite emit_line_0 to have fewer (nested) conditions. The change in 'emit_line' makes sure that 'first' is never user data, but always under our control, a sign or special character in the beginning of the line (or 0, in which case we ignore it). So from now on, let's pass only a diff marker or 0 as the 'first' character of the line. Signed-off-by: Stefan Beller Signed-off-by: Junio C Hamano --- diff.c | 73 ++++++++++++++++++++++++++++++++++++------------------------------ 1 file changed, 40 insertions(+), 33 deletions(-) (limited to 'diff.c') diff --git a/diff.c b/diff.c index 7a23adf254..c5c7739ce3 100644 --- a/diff.c +++ b/diff.c @@ -626,43 +626,50 @@ static void emit_line_0(struct diff_options *o, int first, const char *line, int len) { int has_trailing_newline, has_trailing_carriage_return; - int nofirst; + int needs_reset = 0; /* at the end of the line */ FILE *file = o->file; 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; - } - - if (len || !nofirst) { - if (reverse && want_color(o->use_color)) - fputs(GIT_COLOR_REVERSE, file); - if (set_sign) - fputs(set_sign, file); - if (first && !nofirst) - fputc(first, file); - if (len) { - if (set && set != set_sign) { - if (set_sign) - fputs(reset, file); - fputs(set, file); - } - fwrite(line, len, 1, file); - } - fputs(reset, file); + 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 && !first) + goto end_of_line; + + if (reverse && want_color(o->use_color)) { + fputs(GIT_COLOR_REVERSE, file); + needs_reset = 1; + } + + if (set_sign) { + fputs(set_sign, file); + needs_reset = 1; } + + if (first) + fputc(first, file); + + if (!len) + goto end_of_line; + + if (set) { + if (set_sign && set != set_sign) + fputs(reset, file); + fputs(set, file); + needs_reset = 1; + } + fwrite(line, len, 1, file); + needs_reset = 1; /* 'line' may contain color codes. */ + +end_of_line: + if (needs_reset) + fputs(reset, file); if (has_trailing_carriage_return) fputc('\r', file); if (has_trailing_newline) @@ -672,7 +679,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, NULL, 0, reset, line[0], line+1, len-1); + emit_line_0(o, set, NULL, 0, reset, 0, line, len); } enum diff_symbol { -- cgit v1.2.3 From 7648b79eeefc23e773a41b24e3ecdadb9fe93643 Mon Sep 17 00:00:00 2001 From: Stefan Beller Date: Fri, 17 Aug 2018 13:43:52 -0700 Subject: diff.c: add --output-indicator-{new, old, context} This will prove useful in range-diff in a later patch as we will be able to differentiate between adding a new file (that line is starting with +++ and then the file name) and regular new lines. It could also be useful for experimentation in new patch formats, i.e. we could teach git to emit moved lines with lines other than +/-. Signed-off-by: Stefan Beller Signed-off-by: Junio C Hamano --- diff.c | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) (limited to 'diff.c') diff --git a/diff.c b/diff.c index c5c7739ce3..03486c35b7 100644 --- a/diff.c +++ b/diff.c @@ -1281,7 +1281,9 @@ static void emit_diff_symbol_from_struct(struct diff_options *o, else if (c == '-') set = diff_get_color_opt(o, DIFF_FILE_OLD); } - emit_line_ws_markup(o, set_sign, set, reset, ' ', line, len, + emit_line_ws_markup(o, set_sign, set, reset, + o->output_indicators[OUTPUT_INDICATOR_CONTEXT], + line, len, flags & (DIFF_SYMBOL_CONTENT_WS_MASK), 0); break; case DIFF_SYMBOL_PLUS: @@ -1324,7 +1326,9 @@ static void emit_diff_symbol_from_struct(struct diff_options *o, set = diff_get_color_opt(o, DIFF_CONTEXT_BOLD); flags &= ~DIFF_SYMBOL_CONTENT_WS_MASK; } - emit_line_ws_markup(o, set_sign, set, reset, '+', line, len, + emit_line_ws_markup(o, set_sign, set, reset, + o->output_indicators[OUTPUT_INDICATOR_NEW], + line, len, flags & DIFF_SYMBOL_CONTENT_WS_MASK, flags & DIFF_SYMBOL_CONTENT_BLANK_LINE_EOF); break; @@ -1367,7 +1371,9 @@ static void emit_diff_symbol_from_struct(struct diff_options *o, else set = diff_get_color_opt(o, DIFF_CONTEXT_DIM); } - emit_line_ws_markup(o, set_sign, set, reset, '-', line, len, + emit_line_ws_markup(o, set_sign, set, reset, + o->output_indicators[OUTPUT_INDICATOR_OLD], + line, len, flags & DIFF_SYMBOL_CONTENT_WS_MASK, 0); break; case DIFF_SYMBOL_WORDS_PORCELAIN: @@ -4382,6 +4388,9 @@ void diff_setup(struct diff_options *options) options->file = stdout; + options->output_indicators[OUTPUT_INDICATOR_NEW] = '+'; + options->output_indicators[OUTPUT_INDICATOR_OLD] = '-'; + options->output_indicators[OUTPUT_INDICATOR_CONTEXT] = ' '; options->abbrev = DEFAULT_ABBREV; options->line_termination = '\n'; options->break_opt = -1; @@ -4869,6 +4878,12 @@ int diff_opt_parse(struct diff_options *options, options->output_format |= DIFF_FORMAT_DIFFSTAT; } else if (!strcmp(arg, "--no-compact-summary")) options->flags.stat_with_summary = 0; + else if (skip_prefix(arg, "--output-indicator-new=", &arg)) + options->output_indicators[OUTPUT_INDICATOR_NEW] = arg[0]; + else if (skip_prefix(arg, "--output-indicator-old=", &arg)) + options->output_indicators[OUTPUT_INDICATOR_OLD] = arg[0]; + else if (skip_prefix(arg, "--output-indicator-context=", &arg)) + options->output_indicators[OUTPUT_INDICATOR_CONTEXT] = arg[0]; /* renames options */ else if (starts_with(arg, "-B") || -- cgit v1.2.3