convert.c: simplify text_stat

Simplify the statistics: lonecr counts the CR which is not followed by a LF, lonelf counts the LF which is not preceded by a CR, crlf counts CRLF combinations. This simplifies the evaluation of the statistics. Signed-off-by: Torsten Bögershausen <tboegi@web.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Torsten Bögershausen committed Feb 10, 2016 at 17:24 UTC 6e336a530b0dd98d1c751440ca5666a6999ab020
1 file changed +22 -25
convert.c
+22 -25
@@ -31,7 +31,7 @@ enum crlf_action {
31
32 struct text_stat {
33 /* NUL, CR, LF and CRLF counts */
34 - unsigned nul, cr, lf, crlf;
34 + unsigned nul, lonecr, lonelf, crlf;
35
36 /* These are just approximations! */
37 unsigned printable, nonprintable;
@@ -46,13 +46,15 @@ static void gather_stats(const char *buf, unsigned long size, struct text_stat *
46 for (i = 0; i < size; i++) {
47 unsigned char c = buf[i];
48 if (c == '\r') {
49 - stats->cr++;
50 - if (i+1 < size && buf[i+1] == '\n')
49 + if (i+1 < size && buf[i+1] == '\n') {
50 stats->crlf++;
51 + i++;
52 + } else
53 + stats->lonecr++;
54 continue;
55 }
56 if (c == '\n') {
55 - stats->lf++;
57 + stats->lonelf++;
58 continue;
59 }
60 if (c == 127)
@@ -86,7 +88,7 @@ static void gather_stats(const char *buf, unsigned long size, struct text_stat *
88 */
89 static int convert_is_binary(unsigned long size, const struct text_stat *stats)
90 {
89 - if (stats->cr != stats->crlf)
91 + if (stats->lonecr)
92 return 1;
93 if (stats->nul)
94 return 1;
@@ -98,19 +100,18 @@ static int convert_is_binary(unsigned long size, const struct text_stat *stats)
100 static unsigned int gather_convert_stats(const char *data, unsigned long size)
101 {
102 struct text_stat stats;
103 + int ret = 0;
104 if (!data || !size)
105 return 0;
106 gather_stats(data, size, &stats);
107 if (convert_is_binary(size, &stats))
105 - return CONVERT_STAT_BITS_BIN;
106 - else if (stats.crlf && stats.crlf == stats.lf)
107 - return CONVERT_STAT_BITS_TXT_CRLF;
108 - else if (stats.crlf && stats.lf)
109 - return CONVERT_STAT_BITS_TXT_CRLF | CONVERT_STAT_BITS_TXT_LF;
110 - else if (stats.lf)
111 - return CONVERT_STAT_BITS_TXT_LF;
112 - else
113 - return 0;
108 + ret |= CONVERT_STAT_BITS_BIN;
109 + if (stats.crlf)
110 + ret |= CONVERT_STAT_BITS_TXT_CRLF;
111 + if (stats.lonelf)
112 + ret |= CONVERT_STAT_BITS_TXT_LF;
113 +
114 + return ret;
115 }
116
117 static const char *gather_convert_stats_ascii(const char *data, unsigned long size)
@@ -207,7 +208,7 @@ static void check_safe_crlf(const char *path, enum crlf_action crlf_action,
208 * CRLFs would be added by checkout:
209 * check if we have "naked" LFs
210 */
210 - if (stats->lf != stats->crlf) {
211 + if (stats->lonelf) {
212 if (checksafe == SAFE_CRLF_WARN)
213 warning("LF will be replaced by CRLF in %s.\nThe file will have its original line endings in your working directory.", path);
214 else /* i.e. SAFE_CRLF_FAIL */
@@ -266,8 +267,8 @@ static int crlf_to_git(const char *path, const char *src, size_t len,
267
268 check_safe_crlf(path, crlf_action, &stats, checksafe);
269
269 - /* Optimization: No CR? Nothing to convert, regardless. */
270 - if (!stats.cr)
270 + /* Optimization: No CRLF? Nothing to convert, regardless. */
271 + if (!stats.crlf)
272 return 0;
273
274 /*
@@ -314,19 +315,15 @@ static int crlf_to_worktree(const char *path, const char *src, size_t len,
315
316 gather_stats(src, len, &stats);
317
317 - /* No LF? Nothing to convert, regardless. */
318 - if (!stats.lf)
319 - return 0;
320 -
321 - /* Was it already in CRLF format? */
322 - if (stats.lf == stats.crlf)
318 + /* No "naked" LF? Nothing to convert, regardless. */
319 + if (!stats.lonelf)
320 return 0;
321
322 if (crlf_action == CRLF_AUTO || crlf_action == CRLF_AUTO_INPUT || crlf_action == CRLF_AUTO_CRLF) {
323 if (crlf_action == CRLF_AUTO_INPUT || crlf_action == CRLF_AUTO_CRLF) {
324 /* If we have any CR or CRLF line endings, we do not touch it */
325 /* This is the new safer autocrlf-handling */
329 - if (stats.cr > 0 || stats.crlf > 0)
326 + if (stats.lonecr || stats.crlf )
327 return 0;
328 }
329
@@ -338,7 +335,7 @@ static int crlf_to_worktree(const char *path, const char *src, size_t len,
335 if (src == buf->buf)
336 to_free = strbuf_detach(buf, NULL);
337
341 - strbuf_grow(buf, len + stats.lf - stats.crlf);
338 + strbuf_grow(buf, len + stats.lonelf);
339 for (;;) {
340 const char *nl = memchr(src, '\n', len);
341 if (!nl)