convert.c: refactor crlf_action

Refactor the determination and usage of crlf_action. Today, when no "crlf" attribute are set on a file, crlf_action is set to CRLF_GUESS. Use CRLF_UNDEFINED instead, and search for "text" or "eol" as before. After searching for line ending attributes, save the value in struct conv_attrs.crlf_action attr_action, so that get_convert_attr_ascii() is able report the attributes. Replace the old CRLF_GUESS usage: CRLF_GUESS && core.autocrlf=true -> CRLF_AUTO_CRLF CRLF_GUESS && core.autocrlf=false -> CRLF_BINARY CRLF_GUESS && core.autocrlf=input -> CRLF_AUTO_INPUT Save the action in conv_attrs.crlf_action (as before) and change all callers. Make more clear, what is what, by defining: - CRLF_UNDEFINED : No attributes set. Temparally used, until core.autocrlf and core.eol is evaluated and one of CRLF_BINARY, CRLF_AUTO_INPUT or CRLF_AUTO_CRLF is selected - CRLF_BINARY : No processing of line endings. - CRLF_TEXT : attribute "text" is set, line endings are processed. - CRLF_TEXT_INPUT: attribute "input" or "eol=lf" is set. This implies text. - CRLF_TEXT_CRLF : attribute "eol=crlf" is set. This implies text. - CRLF_AUTO : attribute "auto" is set. - CRLF_AUTO_INPUT: core.autocrlf=input (no attributes) - CRLF_AUTO_CRLF : core.autocrlf=true (no attributes) 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 df747b818f0c9b7d0db1d7e3837b78e5d48b6fde
1 file changed +46 -31
convert.c
+46 -31
@@ -19,12 +19,14 @@
19 #define CONVERT_STAT_BITS_BIN 0x4
20
21 enum crlf_action {
22 - CRLF_GUESS = -1,
23 - CRLF_BINARY = 0,
22 + CRLF_UNDEFINED,
23 + CRLF_BINARY,
24 CRLF_TEXT,
25 - CRLF_INPUT,
26 - CRLF_CRLF,
27 - CRLF_AUTO
25 + CRLF_TEXT_INPUT,
26 + CRLF_TEXT_CRLF,
27 + CRLF_AUTO,
28 + CRLF_AUTO_INPUT,
29 + CRLF_AUTO_CRLF
30 };
31
32 struct text_stat {
@@ -167,18 +169,19 @@ static enum eol output_eol(enum crlf_action crlf_action)
169 switch (crlf_action) {
170 case CRLF_BINARY:
171 return EOL_UNSET;
170 - case CRLF_CRLF:
172 + case CRLF_TEXT_CRLF:
173 return EOL_CRLF;
172 - case CRLF_INPUT:
174 + case CRLF_TEXT_INPUT:
175 return EOL_LF;
174 - case CRLF_GUESS:
175 - if (!auto_crlf)
176 - return EOL_UNSET;
177 - /* fall through */
176 + case CRLF_UNDEFINED:
177 + case CRLF_AUTO_CRLF:
178 + case CRLF_AUTO_INPUT:
179 case CRLF_TEXT:
180 case CRLF_AUTO:
181 + /* fall through */
182 return text_eol_is_crlf() ? EOL_CRLF : EOL_LF;
183 }
184 + warning("Illegal crlf_action %d\n", (int)crlf_action);
185 return core_eol;
186 }
187
@@ -235,7 +238,6 @@ static int crlf_to_git(const char *path, const char *src, size_t len,
238 char *dst;
239
240 if (crlf_action == CRLF_BINARY ||
238 - (crlf_action == CRLF_GUESS && auto_crlf == AUTO_CRLF_FALSE) ||
241 (src && !len))
242 return 0;
243
@@ -248,11 +250,11 @@ static int crlf_to_git(const char *path, const char *src, size_t len,
250
251 gather_stats(src, len, &stats);
252
251 - if (crlf_action == CRLF_AUTO || crlf_action == CRLF_GUESS) {
253 + if (crlf_action == CRLF_AUTO || crlf_action == CRLF_AUTO_INPUT || crlf_action == CRLF_AUTO_CRLF) {
254 if (convert_is_binary(len, &stats))
255 return 0;
256
255 - if (crlf_action == CRLF_GUESS) {
257 + if (crlf_action == CRLF_AUTO_INPUT || crlf_action == CRLF_AUTO_CRLF) {
258 /*
259 * If the file in the index has any CR in it, do not convert.
260 * This is the new safer autocrlf handling.
@@ -279,7 +281,7 @@ static int crlf_to_git(const char *path, const char *src, size_t len,
281 if (strbuf_avail(buf) + buf->len < len)
282 strbuf_grow(buf, len - buf->len);
283 dst = buf->buf;
282 - if (crlf_action == CRLF_AUTO || crlf_action == CRLF_GUESS) {
284 + if (crlf_action == CRLF_AUTO || crlf_action == CRLF_AUTO_INPUT || crlf_action == CRLF_AUTO_CRLF) {
285 /*
286 * If we guessed, we already know we rejected a file with
287 * lone CR, and we can strip a CR without looking at what
@@ -320,8 +322,8 @@ static int crlf_to_worktree(const char *path, const char *src, size_t len,
322 if (stats.lf == stats.crlf)
323 return 0;
324
323 - if (crlf_action == CRLF_AUTO || crlf_action == CRLF_GUESS) {
324 - if (crlf_action == CRLF_GUESS) {
325 + if (crlf_action == CRLF_AUTO || crlf_action == CRLF_AUTO_INPUT || crlf_action == CRLF_AUTO_CRLF) {
326 + if (crlf_action == CRLF_AUTO_INPUT || crlf_action == CRLF_AUTO_CRLF) {
327 /* If we have any CR or CRLF line endings, we do not touch it */
328 /* This is the new safer autocrlf-handling */
329 if (stats.cr > 0 || stats.crlf > 0)
@@ -709,16 +711,16 @@ static enum crlf_action git_path_check_crlf(struct git_attr_check *check)
711 const char *value = check->value;
712
713 if (ATTR_TRUE(value))
712 - return CRLF_TEXT;
714 + return text_eol_is_crlf() ? CRLF_TEXT_CRLF : CRLF_TEXT_INPUT;
715 else if (ATTR_FALSE(value))
716 return CRLF_BINARY;
717 else if (ATTR_UNSET(value))
718 ;
719 else if (!strcmp(value, "input"))
718 - return CRLF_INPUT;
720 + return CRLF_TEXT_INPUT;
721 else if (!strcmp(value, "auto"))
722 return CRLF_AUTO;
721 - return CRLF_GUESS;
723 + return CRLF_UNDEFINED;
724 }
725
726 static enum eol git_path_check_eol(struct git_attr_check *check)
@@ -781,7 +783,7 @@ static void convert_attrs(struct conv_attrs *ca, const char *path)
783 if (!git_check_attr(path, NUM_CONV_ATTRS, ccheck)) {
784 enum eol eol_attr;
785 ca->crlf_action = git_path_check_crlf(ccheck + 4);
784 - if (ca->crlf_action == CRLF_GUESS)
786 + if (ca->crlf_action == CRLF_UNDEFINED)
787 ca->crlf_action = git_path_check_crlf(ccheck + 0);
788 ca->attr_action = ca->crlf_action;
789 ca->ident = git_path_check_ident(ccheck + 1);
@@ -790,14 +792,22 @@ static void convert_attrs(struct conv_attrs *ca, const char *path)
792 return;
793 eol_attr = git_path_check_eol(ccheck + 3);
794 if (eol_attr == EOL_LF)
793 - ca->crlf_action = CRLF_INPUT;
795 + ca->crlf_action = CRLF_TEXT_INPUT;
796 else if (eol_attr == EOL_CRLF)
795 - ca->crlf_action = CRLF_CRLF;
797 + ca->crlf_action = CRLF_TEXT_CRLF;
798 } else {
799 ca->drv = NULL;
798 - ca->crlf_action = CRLF_GUESS;
800 + ca->crlf_action = CRLF_UNDEFINED;
801 ca->ident = 0;
802 }
803 + if (ca->crlf_action == CRLF_TEXT)
804 + ca->crlf_action = text_eol_is_crlf() ? CRLF_TEXT_CRLF : CRLF_TEXT_INPUT;
805 + if (ca->crlf_action == CRLF_UNDEFINED && auto_crlf == AUTO_CRLF_FALSE)
806 + ca->crlf_action = CRLF_BINARY;
807 + if (ca->crlf_action == CRLF_UNDEFINED && auto_crlf == AUTO_CRLF_TRUE)
808 + ca->crlf_action = CRLF_AUTO_CRLF;
809 + if (ca->crlf_action == CRLF_UNDEFINED && auto_crlf == AUTO_CRLF_INPUT)
810 + ca->crlf_action = CRLF_AUTO_INPUT;
811 }
812
813 int would_convert_to_git_filter_fd(const char *path)
@@ -825,18 +835,22 @@ const char *get_convert_attr_ascii(const char *path)
835
836 convert_attrs(&ca, path);
837 switch (ca.attr_action) {
828 - case CRLF_GUESS:
838 + case CRLF_UNDEFINED:
839 return "";
840 case CRLF_BINARY:
841 return "-text";
842 case CRLF_TEXT:
843 return "text";
834 - case CRLF_INPUT:
844 + case CRLF_TEXT_INPUT:
845 return "text eol=lf";
836 - case CRLF_CRLF:
837 - return "text=auto eol=crlf";
846 + case CRLF_TEXT_CRLF:
847 + return "text eol=crlf";
848 case CRLF_AUTO:
849 return "text=auto";
850 + case CRLF_AUTO_CRLF:
851 + return "text=auto eol=crlf"; /* This is not supported yet */
852 + case CRLF_AUTO_INPUT:
853 + return "text=auto eol=lf"; /* This is not supported yet */
854 }
855 return "";
856 }
@@ -1382,12 +1396,13 @@ struct stream_filter *get_stream_filter(const char *path, const unsigned char *s
1396
1397 crlf_action = ca.crlf_action;
1398
1385 - if ((crlf_action == CRLF_BINARY) || (crlf_action == CRLF_INPUT) ||
1386 - (crlf_action == CRLF_GUESS && auto_crlf == AUTO_CRLF_FALSE))
1399 + if ((crlf_action == CRLF_BINARY) ||
1400 + crlf_action == CRLF_AUTO_INPUT ||
1401 + (crlf_action == CRLF_TEXT_INPUT))
1402 filter = cascade_filter(filter, &null_filter_singleton);
1403
1404 else if (output_eol(crlf_action) == EOL_CRLF &&
1390 - !(crlf_action == CRLF_AUTO || crlf_action == CRLF_GUESS))
1405 + !(crlf_action == CRLF_AUTO || crlf_action == CRLF_AUTO_CRLF))
1406 filter = cascade_filter(filter, lf_to_crlf_filter());
1407
1408 return filter;