From: Junio C Hamano Date: Wed, 14 Dec 2011 06:49:45 +0000 (-0800) Subject: Merge branch 'cn/maint-lf-to-crlf-filter' X-Git-Tag: v1.7.9-rc0~70 X-Git-Url: https://git.lorimer.id.au/gitweb.git/diff_plain/a96a89f7153150c7e59d5481dd22773173b5a877?ds=inline;hp=-c Merge branch 'cn/maint-lf-to-crlf-filter' * cn/maint-lf-to-crlf-filter: convert: track state in LF-to-CRLF filter --- a96a89f7153150c7e59d5481dd22773173b5a877 diff --combined convert.c index 86e9c29ec0,c2c2c1144d..346f9d45e0 --- 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,39 +876,39 @@@ int is_null_stream_filter(struct stream /* * LF-to-CRLF filter */ + + struct lf_to_crlf_filter { + struct stream_filter filter; + int want_lf; + }; + 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; + } if (!input) - return 0; /* we do not keep any states */ + return 0; /* We've already dealt with the state */ + 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 -919,24 +919,24 @@@ 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 = xmalloc(sizeof(*lf_to_crlf)); + lf_to_crlf->filter.vtbl = &lf_to_crlf_vtbl; + lf_to_crlf->want_lf = 0; + return (struct stream_filter *)lf_to_crlf; + } /* * Cascade filter @@@ -1194,7 -1218,7 +1218,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; }