From: Junio C Hamano Date: Thu, 22 Dec 2011 19:27:29 +0000 (-0800) Subject: Merge branch 'jc/maint-lf-to-crlf-keep-crlf' X-Git-Tag: v1.7.9-rc0~20 X-Git-Url: https://git.lorimer.id.au/gitweb.git/diff_plain/339aff0846ccf21905d047c20e3c7d077d6f300b?ds=inline;hp=-c Merge branch 'jc/maint-lf-to-crlf-keep-crlf' * jc/maint-lf-to-crlf-keep-crlf: lf_to_crlf_filter(): resurrect CRLF->CRLF hack --- 339aff0846ccf21905d047c20e3c7d077d6f300b diff --combined convert.c index c9ab54ffd2,8daf4e48e5..12868ed7bd --- a/convert.c +++ b/convert.c @@@ -641,7 -641,7 +641,7 @@@ static int ident_to_worktree(const cha return 1; } -static int git_path_check_crlf(const char *path, struct git_attr_check *check) +static enum crlf_action git_path_check_crlf(const char *path, struct git_attr_check *check) { const char *value = check->value; @@@ -658,7 -658,7 +658,7 @@@ return CRLF_GUESS; } -static int git_path_check_eol(const char *path, struct git_attr_check *check) +static enum eol git_path_check_eol(const char *path, struct git_attr_check *check) { const char *value = check->value; @@@ -811,7 -811,7 +811,7 @@@ int renormalize_buffer(const char *path src = dst->buf; len = dst->len; } - return ret | convert_to_git(path, src, len, dst, 0); + return ret | convert_to_git(path, src, len, dst, SAFE_CRLF_FALSE); } /***************************************************************** @@@ -879,7 -879,8 +879,8 @@@ int is_null_stream_filter(struct stream struct lf_to_crlf_filter { struct stream_filter filter; - unsigned want_lf:1; + unsigned has_held:1; + char held; }; static int lf_to_crlf_filter_fn(struct stream_filter *filter, @@@ -889,10 -890,14 +890,14 @@@ size_t count, o = 0; struct lf_to_crlf_filter *lf_to_crlf = (struct lf_to_crlf_filter *)filter; - /* Output a pending LF if we need to */ - if (lf_to_crlf->want_lf) { - output[o++] = '\n'; - lf_to_crlf->want_lf = 0; + /* + * We may be holding onto the CR to see if it is followed by a + * LF, in which case we would need to go to the main loop. + * Otherwise, just emit it to the output stream. + */ + if (lf_to_crlf->has_held && (lf_to_crlf->held != '\r' || !input)) { + output[o++] = lf_to_crlf->held; + lf_to_crlf->has_held = 0; } /* We are told to drain */ @@@ -902,22 -907,57 +907,57 @@@ } count = *isize_p; - if (count) { + if (count || lf_to_crlf->has_held) { size_t i; + int was_cr = 0; + + if (lf_to_crlf->has_held) { + was_cr = 1; + lf_to_crlf->has_held = 0; + } + for (i = 0; o < *osize_p && i < count; i++) { char ch = input[i]; + if (ch == '\n') { output[o++] = '\r'; - if (o >= *osize_p) { - lf_to_crlf->want_lf = 1; - continue; /* We need to increase i */ - } + } else if (was_cr) { + /* + * Previous round saw CR and it is not followed + * by a LF; emit the CR before processing the + * current character. + */ + output[o++] = '\r'; } + + /* + * We may have consumed the last output slot, + * in which case we need to break out of this + * loop; hold the current character before + * returning. + */ + if (*osize_p <= o) { + lf_to_crlf->has_held = 1; + lf_to_crlf->held = ch; + continue; /* break but increment i */ + } + + if (ch == '\r') { + was_cr = 1; + continue; + } + + was_cr = 0; output[o++] = ch; } *osize_p -= o; *isize_p -= i; + + if (!lf_to_crlf->has_held && was_cr) { + lf_to_crlf->has_held = 1; + lf_to_crlf->held = '\r'; + } } return 0; }