On 05/13, Stefan Beller wrote:
> In 250f79930d (diff.c: split emit_line() from the first char and the rest
> of the line, 2009-09-14) we introduced the local variable 'nofirst' that
> indicates if we have no first sign character. With the given implementation
> we had to use an extra variable unlike reusing 'first' because the lines
> first character could be '\0'.
>
> Change the meaning of the 'first' argument to not mean the first character
> of the line, but rather just containing the sign that is prepended to the
> line. Refactor emit_line to not include the lines first character, but pass
> the complete line as well as a '\0' sign, which now serves as an indication
> not to print a sign.
>
> With this patch other callers hard code the sign (which are '+', '-',
> ' ' and '\\') such that we do not run into unexpectedly emitting an
> error-nous '\0'.
>
> The audit of the caller revealed that the sign cannot be '\n' or '\r',
> so remove that condition for trailing newline or carriage return in the
> sign; the else part of the condition handles the len==0 perfectly,
> so we can drop the if/else construct.
>
> Signed-off-by: Stefan Beller <[email protected]>
> ---
> diff.c | 40 +++++++++++++++++-----------------------
> 1 file changed, 17 insertions(+), 23 deletions(-)
>
> diff --git a/diff.c b/diff.c
> index c2ed605cd0..4269b8dccf 100644
> --- a/diff.c
> +++ b/diff.c
> @@ -517,33 +517,24 @@ static void check_blank_at_eof(mmfile_t *mf1, mmfile_t
> *mf2,
> }
>
> static void emit_line_0(struct diff_options *o, const char *set, const char
> *reset,
> - int first, const char *line, int len)
> + int sign, const char *line, int len)
> {
> int has_trailing_newline, has_trailing_carriage_return;
> - int nofirst;
> 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;
> - }
> + 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--;
Does the order of newline/carriage return always the same?
>
> - if (len || !nofirst) {
> + if (len || sign) {
> fputs(set, file);
> - if (!nofirst)
> - fputc(first, file);
> + if (sign)
> + fputc(sign, file);
> fwrite(line, len, 1, file);
> fputs(reset, file);
> }
> @@ -556,7 +547,7 @@ static void emit_line_0(struct diff_options *o, const
> char *set, const char *res
> static void emit_line(struct diff_options *o, const char *set, const char
> *reset,
> const char *line, int len)
> {
> - emit_line_0(o, set, reset, line[0], line+1, len-1);
> + emit_line_0(o, set, reset, 0, line, len);
> }
>
> static int new_blank_line_at_eof(struct emit_callback *ecbdata, const char
> *line, int len)
> @@ -4822,9 +4813,12 @@ void diff_flush(struct diff_options *options)
>
> if (output_format & DIFF_FORMAT_PATCH) {
> if (separator) {
> - fprintf(options->file, "%s%c",
> - diff_line_prefix(options),
> - options->line_termination);
> + char term[2];
> + term[0] = options->line_termination;
> + term[1] = '\0';
> +
> + emit_line(options, NULL, NULL,
> + term, 1);
> if (options->stat_sep) {
> /* attach patch instead of inline */
> fputs(options->stat_sep, options->file);
> --
> 2.13.0.18.g183880de0a
>
--
Brandon Williams