From: Junio C Hamano Date: Wed, 21 Dec 2011 19:42:44 +0000 (-0800) Subject: Merge branch 'cn/maint-lf-to-crlf-filter' into maint X-Git-Tag: v1.7.8.1~4 X-Git-Url: https://git.lorimer.id.au/gitweb.git/diff_plain/3bb8d69cddbcad4bd4ae3d1281c42c1aeb297355?ds=inline;hp=-c Merge branch 'cn/maint-lf-to-crlf-filter' into maint * cn/maint-lf-to-crlf-filter: lf_to_crlf_filter(): tell the caller we added "\n" when draining convert: track state in LF-to-CRLF filter --- 3bb8d69cddbcad4bd4ae3d1281c42c1aeb297355 diff --combined convert.c index 86e9c29ec0,c028275c14..c9ab54ffd2 --- 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); } /***************************************************************** @@@ -876,24 -876,42 +876,42 @@@ int is_null_stream_filter(struct stream /* * LF-to-CRLF filter */ + + struct lf_to_crlf_filter { + struct stream_filter filter; + unsigned want_lf:1; + }; + static int lf_to_crlf_filter_fn(struct stream_filter *filter, const char *input, size_t *isize_p, char *output, size_t *osize_p) { - size_t count; + 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 are told to drain */ + if (!input) { + *osize_p -= o; + return 0; + } - if (!input) - return 0; /* we do not keep any states */ count = *isize_p; if (count) { - size_t i, o; - for (i = o = 0; o < *osize_p && i < count; i++) { + size_t i; + for (i = 0; o < *osize_p && i < count; i++) { char ch = input[i]; if (ch == '\n') { - if (o + 1 < *osize_p) - output[o++] = '\r'; - else - break; + output[o++] = '\r'; + if (o >= *osize_p) { + lf_to_crlf->want_lf = 1; + continue; /* We need to increase i */ + } } output[o++] = ch; } @@@ -904,15 -922,23 +922,23 @@@ return 0; } + static void lf_to_crlf_free_fn(struct stream_filter *filter) + { + free(filter); + } + static struct stream_filter_vtbl lf_to_crlf_vtbl = { lf_to_crlf_filter_fn, - null_free_fn, + lf_to_crlf_free_fn, }; - static struct stream_filter lf_to_crlf_filter_singleton = { - &lf_to_crlf_vtbl, - }; + static struct stream_filter *lf_to_crlf_filter(void) + { + struct lf_to_crlf_filter *lf_to_crlf = xcalloc(1, sizeof(*lf_to_crlf)); + lf_to_crlf->filter.vtbl = &lf_to_crlf_vtbl; + return (struct stream_filter *)lf_to_crlf; + } /* * Cascade filter @@@ -1194,7 -1220,7 +1220,7 @@@ struct stream_filter *get_stream_filter else if (output_eol(crlf_action) == EOL_CRLF && !(crlf_action == CRLF_AUTO || crlf_action == CRLF_GUESS)) - filter = cascade_filter(filter, &lf_to_crlf_filter_singleton); + filter = cascade_filter(filter, lf_to_crlf_filter()); return filter; }