Skip to content

Commit fb53969

Browse files
committed
Merge branch 'jc/convert'
* jc/convert: convert: make it harder to screw up adding a conversion attribute convert: make it safer to add conversion attributes convert: give saner names to crlf/eol variables, types and functions convert: rename the "eol" global variable to "core_eol"
2 parents 7a77754 + 3bfba20 commit fb53969

File tree

4 files changed

+84
-90
lines changed

4 files changed

+84
-90
lines changed

cache.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -606,7 +606,7 @@ enum eol {
606606
#endif
607607
};
608608

609-
extern enum eol eol;
609+
extern enum eol core_eol;
610610

611611
enum branch_track {
612612
BRANCH_TRACK_UNSPECIFIED = -1,

config.c

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -583,7 +583,7 @@ static int git_default_core_config(const char *var, const char *value)
583583

584584
if (!strcmp(var, "core.autocrlf")) {
585585
if (value && !strcasecmp(value, "input")) {
586-
if (eol == EOL_CRLF)
586+
if (core_eol == EOL_CRLF)
587587
return error("core.autocrlf=input conflicts with core.eol=crlf");
588588
auto_crlf = AUTO_CRLF_INPUT;
589589
return 0;
@@ -603,14 +603,14 @@ static int git_default_core_config(const char *var, const char *value)
603603

604604
if (!strcmp(var, "core.eol")) {
605605
if (value && !strcasecmp(value, "lf"))
606-
eol = EOL_LF;
606+
core_eol = EOL_LF;
607607
else if (value && !strcasecmp(value, "crlf"))
608-
eol = EOL_CRLF;
608+
core_eol = EOL_CRLF;
609609
else if (value && !strcasecmp(value, "native"))
610-
eol = EOL_NATIVE;
610+
core_eol = EOL_NATIVE;
611611
else
612-
eol = EOL_UNSET;
613-
if (eol == EOL_CRLF && auto_crlf == AUTO_CRLF_INPUT)
612+
core_eol = EOL_UNSET;
613+
if (core_eol == EOL_CRLF && auto_crlf == AUTO_CRLF_INPUT)
614614
return error("core.autocrlf=input conflicts with core.eol=crlf");
615615
return 0;
616616
}

convert.c

Lines changed: 76 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
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

190190
static 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

259260
static 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-
501478
static 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+
729745
int 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

765770
static 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;

environment.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ const char *askpass_program;
4343
const char *excludes_file;
4444
enum auto_crlf auto_crlf = AUTO_CRLF_FALSE;
4545
int read_replace_refs = 1;
46-
enum eol eol = EOL_UNSET;
46+
enum eol core_eol = EOL_UNSET;
4747
enum safe_crlf safe_crlf = SAFE_CRLF_WARN;
4848
unsigned whitespace_rule_cfg = WS_DEFAULT_RULE;
4949
enum branch_track git_branch_track = BRANCH_TRACK_REMOTE;

0 commit comments

Comments
 (0)