1212 * translation when the "text" attribute or "auto_crlf" option is set.
1313 */
1414
15- enum action {
15+ enum crlf_action {
1616 CRLF_GUESS = -1 ,
1717 CRLF_BINARY = 0 ,
1818 CRLF_TEXT ,
@@ -94,9 +94,9 @@ static int is_binary(unsigned long size, struct text_stat *stats)
9494 return 0 ;
9595}
9696
97- static enum eol determine_output_conversion (enum action action )
97+ static enum eol output_eol (enum crlf_action crlf_action )
9898{
99- switch (action ) {
99+ switch (crlf_action ) {
100100 case CRLF_BINARY :
101101 return EOL_UNSET ;
102102 case CRLF_CRLF :
@@ -113,19 +113,19 @@ static enum eol determine_output_conversion(enum action action)
113113 return EOL_CRLF ;
114114 else if (auto_crlf == AUTO_CRLF_INPUT )
115115 return EOL_LF ;
116- else if (eol == EOL_UNSET )
116+ else if (core_eol == EOL_UNSET )
117117 return EOL_NATIVE ;
118118 }
119- return eol ;
119+ return core_eol ;
120120}
121121
122- static void check_safe_crlf (const char * path , enum action action ,
122+ static void check_safe_crlf (const char * path , enum crlf_action crlf_action ,
123123 struct text_stat * stats , enum safe_crlf checksafe )
124124{
125125 if (!checksafe )
126126 return ;
127127
128- if (determine_output_conversion ( action ) == EOL_LF ) {
128+ if (output_eol ( crlf_action ) == EOL_LF ) {
129129 /*
130130 * CRLFs would not be restored by checkout:
131131 * check if we'd remove CRLFs
@@ -136,7 +136,7 @@ static void check_safe_crlf(const char *path, enum action action,
136136 else /* i.e. SAFE_CRLF_FAIL */
137137 die ("CRLF would be replaced by LF in %s." , path );
138138 }
139- } else if (determine_output_conversion ( action ) == EOL_CRLF ) {
139+ } else if (output_eol ( crlf_action ) == EOL_CRLF ) {
140140 /*
141141 * CRLFs would be added by checkout:
142142 * check if we have "naked" LFs
@@ -188,18 +188,19 @@ static int has_cr_in_index(const char *path)
188188}
189189
190190static int crlf_to_git (const char * path , const char * src , size_t len ,
191- struct strbuf * buf , enum action action , enum safe_crlf checksafe )
191+ struct strbuf * buf ,
192+ enum crlf_action crlf_action , enum safe_crlf checksafe )
192193{
193194 struct text_stat stats ;
194195 char * dst ;
195196
196- if (action == CRLF_BINARY ||
197- (action == CRLF_GUESS && auto_crlf == AUTO_CRLF_FALSE ) || !len )
197+ if (crlf_action == CRLF_BINARY ||
198+ (crlf_action == CRLF_GUESS && auto_crlf == AUTO_CRLF_FALSE ) || !len )
198199 return 0 ;
199200
200201 gather_stats (src , len , & stats );
201202
202- if (action == CRLF_AUTO || action == CRLF_GUESS ) {
203+ if (crlf_action == CRLF_AUTO || crlf_action == CRLF_GUESS ) {
203204 /*
204205 * We're currently not going to even try to convert stuff
205206 * that has bare CR characters. Does anybody do that crazy
@@ -214,7 +215,7 @@ static int crlf_to_git(const char *path, const char *src, size_t len,
214215 if (is_binary (len , & stats ))
215216 return 0 ;
216217
217- if (action == CRLF_GUESS ) {
218+ if (crlf_action == CRLF_GUESS ) {
218219 /*
219220 * If the file in the index has any CR in it, do not convert.
220221 * This is the new safer autocrlf handling.
@@ -224,7 +225,7 @@ static int crlf_to_git(const char *path, const char *src, size_t len,
224225 }
225226 }
226227
227- check_safe_crlf (path , action , & stats , checksafe );
228+ check_safe_crlf (path , crlf_action , & stats , checksafe );
228229
229230 /* Optimization: No CR? Nothing to convert, regardless. */
230231 if (!stats .cr )
@@ -234,7 +235,7 @@ static int crlf_to_git(const char *path, const char *src, size_t len,
234235 if (strbuf_avail (buf ) + buf -> len < len )
235236 strbuf_grow (buf , len - buf -> len );
236237 dst = buf -> buf ;
237- if (action == CRLF_AUTO || action == CRLF_GUESS ) {
238+ if (crlf_action == CRLF_AUTO || crlf_action == CRLF_GUESS ) {
238239 /*
239240 * If we guessed, we already know we rejected a file with
240241 * lone CR, and we can strip a CR without looking at what
@@ -257,12 +258,12 @@ static int crlf_to_git(const char *path, const char *src, size_t len,
257258}
258259
259260static int crlf_to_worktree (const char * path , const char * src , size_t len ,
260- struct strbuf * buf , enum action action )
261+ struct strbuf * buf , enum crlf_action crlf_action )
261262{
262263 char * to_free = NULL ;
263264 struct text_stat stats ;
264265
265- if (!len || determine_output_conversion ( action ) != EOL_CRLF )
266+ if (!len || output_eol ( crlf_action ) != EOL_CRLF )
266267 return 0 ;
267268
268269 gather_stats (src , len , & stats );
@@ -275,8 +276,8 @@ static int crlf_to_worktree(const char *path, const char *src, size_t len,
275276 if (stats .lf == stats .crlf )
276277 return 0 ;
277278
278- if (action == CRLF_AUTO || action == CRLF_GUESS ) {
279- if (action == CRLF_GUESS ) {
279+ if (crlf_action == CRLF_AUTO || crlf_action == CRLF_GUESS ) {
280+ if (crlf_action == CRLF_GUESS ) {
280281 /* If we have any CR or CRLF line endings, we do not touch it */
281282 /* This is the new safer autocrlf-handling */
282283 if (stats .cr > 0 || stats .crlf > 0 )
@@ -474,30 +475,6 @@ static int read_convert_config(const char *var, const char *value, void *cb)
474475 return 0 ;
475476}
476477
477- static void setup_convert_check (struct git_attr_check * check )
478- {
479- static struct git_attr * attr_text ;
480- static struct git_attr * attr_crlf ;
481- static struct git_attr * attr_eol ;
482- static struct git_attr * attr_ident ;
483- static struct git_attr * attr_filter ;
484-
485- if (!attr_text ) {
486- attr_text = git_attr ("text" );
487- attr_crlf = git_attr ("crlf" );
488- attr_eol = git_attr ("eol" );
489- attr_ident = git_attr ("ident" );
490- attr_filter = git_attr ("filter" );
491- user_convert_tail = & user_convert ;
492- git_config (read_convert_config , NULL );
493- }
494- check [0 ].attr = attr_crlf ;
495- check [1 ].attr = attr_ident ;
496- check [2 ].attr = attr_filter ;
497- check [3 ].attr = attr_eol ;
498- check [4 ].attr = attr_text ;
499- }
500-
501478static int count_ident (const char * cp , unsigned long size )
502479{
503480 /*
@@ -715,7 +692,7 @@ static int git_path_check_ident(const char *path, struct git_attr_check *check)
715692 return !!ATTR_TRUE (value );
716693}
717694
718- static enum action determine_action (enum action text_attr , enum eol eol_attr )
695+ static enum crlf_action input_crlf_action (enum crlf_action text_attr , enum eol eol_attr )
719696{
720697 if (text_attr == CRLF_BINARY )
721698 return CRLF_BINARY ;
@@ -726,66 +703,83 @@ static enum action determine_action(enum action text_attr, enum eol eol_attr)
726703 return text_attr ;
727704}
728705
706+ struct conv_attrs {
707+ struct convert_driver * drv ;
708+ enum crlf_action crlf_action ;
709+ enum eol eol_attr ;
710+ int ident ;
711+ };
712+
713+ static const char * conv_attr_name [] = {
714+ "crlf" , "ident" , "filter" , "eol" , "text" ,
715+ };
716+ #define NUM_CONV_ATTRS ARRAY_SIZE(conv_attr_name)
717+
718+ static void convert_attrs (struct conv_attrs * ca , const char * path )
719+ {
720+ int i ;
721+ static struct git_attr_check ccheck [NUM_CONV_ATTRS ];
722+
723+ if (!ccheck [0 ].attr ) {
724+ for (i = 0 ; i < NUM_CONV_ATTRS ; i ++ )
725+ ccheck [i ].attr = git_attr (conv_attr_name [i ]);
726+ user_convert_tail = & user_convert ;
727+ git_config (read_convert_config , NULL );
728+ }
729+
730+ if (!git_checkattr (path , NUM_CONV_ATTRS , ccheck )) {
731+ ca -> crlf_action = git_path_check_crlf (path , ccheck + 4 );
732+ if (ca -> crlf_action == CRLF_GUESS )
733+ ca -> crlf_action = git_path_check_crlf (path , ccheck + 0 );
734+ ca -> ident = git_path_check_ident (path , ccheck + 1 );
735+ ca -> drv = git_path_check_convert (path , ccheck + 2 );
736+ ca -> eol_attr = git_path_check_eol (path , ccheck + 3 );
737+ } else {
738+ ca -> drv = NULL ;
739+ ca -> crlf_action = CRLF_GUESS ;
740+ ca -> eol_attr = EOL_UNSET ;
741+ ca -> ident = 0 ;
742+ }
743+ }
744+
729745int convert_to_git (const char * path , const char * src , size_t len ,
730746 struct strbuf * dst , enum safe_crlf checksafe )
731747{
732- struct git_attr_check check [5 ];
733- enum action action = CRLF_GUESS ;
734- enum eol eol_attr = EOL_UNSET ;
735- int ident = 0 , ret = 0 ;
748+ int ret = 0 ;
736749 const char * filter = NULL ;
750+ struct conv_attrs ca ;
737751
738- setup_convert_check (check );
739- if (!git_checkattr (path , ARRAY_SIZE (check ), check )) {
740- struct convert_driver * drv ;
741- action = git_path_check_crlf (path , check + 4 );
742- if (action == CRLF_GUESS )
743- action = git_path_check_crlf (path , check + 0 );
744- ident = git_path_check_ident (path , check + 1 );
745- drv = git_path_check_convert (path , check + 2 );
746- eol_attr = git_path_check_eol (path , check + 3 );
747- if (drv && drv -> clean )
748- filter = drv -> clean ;
749- }
752+ convert_attrs (& ca , path );
753+ if (ca .drv )
754+ filter = ca .drv -> clean ;
750755
751756 ret |= apply_filter (path , src , len , dst , filter );
752757 if (ret ) {
753758 src = dst -> buf ;
754759 len = dst -> len ;
755760 }
756- action = determine_action ( action , eol_attr );
757- ret |= crlf_to_git (path , src , len , dst , action , checksafe );
761+ ca . crlf_action = input_crlf_action ( ca . crlf_action , ca . eol_attr );
762+ ret |= crlf_to_git (path , src , len , dst , ca . crlf_action , checksafe );
758763 if (ret ) {
759764 src = dst -> buf ;
760765 len = dst -> len ;
761766 }
762- return ret | ident_to_git (path , src , len , dst , ident );
767+ return ret | ident_to_git (path , src , len , dst , ca . ident );
763768}
764769
765770static int convert_to_working_tree_internal (const char * path , const char * src ,
766771 size_t len , struct strbuf * dst ,
767772 int normalizing )
768773{
769- struct git_attr_check check [5 ];
770- enum action action = CRLF_GUESS ;
771- enum eol eol_attr = EOL_UNSET ;
772- int ident = 0 , ret = 0 ;
774+ int ret = 0 ;
773775 const char * filter = NULL ;
776+ struct conv_attrs ca ;
774777
775- setup_convert_check (check );
776- if (!git_checkattr (path , ARRAY_SIZE (check ), check )) {
777- struct convert_driver * drv ;
778- action = git_path_check_crlf (path , check + 4 );
779- if (action == CRLF_GUESS )
780- action = git_path_check_crlf (path , check + 0 );
781- ident = git_path_check_ident (path , check + 1 );
782- drv = git_path_check_convert (path , check + 2 );
783- eol_attr = git_path_check_eol (path , check + 3 );
784- if (drv && drv -> smudge )
785- filter = drv -> smudge ;
786- }
778+ convert_attrs (& ca , path );
779+ if (ca .drv )
780+ filter = ca .drv -> smudge ;
787781
788- ret |= ident_to_worktree (path , src , len , dst , ident );
782+ ret |= ident_to_worktree (path , src , len , dst , ca . ident );
789783 if (ret ) {
790784 src = dst -> buf ;
791785 len = dst -> len ;
@@ -795,8 +789,8 @@ static int convert_to_working_tree_internal(const char *path, const char *src,
795789 * is a smudge filter. The filter might expect CRLFs.
796790 */
797791 if (filter || !normalizing ) {
798- action = determine_action ( action , eol_attr );
799- ret |= crlf_to_worktree (path , src , len , dst , action );
792+ ca . crlf_action = input_crlf_action ( ca . crlf_action , ca . eol_attr );
793+ ret |= crlf_to_worktree (path , src , len , dst , ca . crlf_action );
800794 if (ret ) {
801795 src = dst -> buf ;
802796 len = dst -> len ;
0 commit comments