Skip to content

Commit 3bfba20

Browse files
committed
convert: make it harder to screw up adding a conversion attribute
The current internal API requires the callers of setup_convert_check() to supply the git_attr_check structures (hence they need to know how many to allocate), but they grab the same set of attributes for given path. Define a new convert_attrs() API that fills a higher level information that the callers (convert_to_git and convert_to_working_tree) really want, and move the common code to interact with the attributes system to it. Signed-off-by: Junio C Hamano <[email protected]>
1 parent 8329596 commit 3bfba20

File tree

1 file changed

+38
-41
lines changed

1 file changed

+38
-41
lines changed

convert.c

Lines changed: 38 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -703,12 +703,19 @@ static enum crlf_action input_crlf_action(enum crlf_action text_attr, enum eol e
703703
return text_attr;
704704
}
705705

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+
706713
static const char *conv_attr_name[] = {
707714
"crlf", "ident", "filter", "eol", "text",
708715
};
709716
#define NUM_CONV_ATTRS ARRAY_SIZE(conv_attr_name)
710717

711-
static void setup_convert_check(struct git_attr_check *check)
718+
static void convert_attrs(struct conv_attrs *ca, const char *path)
712719
{
713720
int i;
714721
static struct git_attr_check ccheck[NUM_CONV_ATTRS];
@@ -719,70 +726,60 @@ static void setup_convert_check(struct git_attr_check *check)
719726
user_convert_tail = &user_convert;
720727
git_config(read_convert_config, NULL);
721728
}
722-
for (i = 0; i < NUM_CONV_ATTRS; i++)
723-
check[i].attr = ccheck[i].attr;
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+
}
724743
}
725744

726745
int convert_to_git(const char *path, const char *src, size_t len,
727746
struct strbuf *dst, enum safe_crlf checksafe)
728747
{
729-
struct git_attr_check check[NUM_CONV_ATTRS];
730-
enum crlf_action crlf_action = CRLF_GUESS;
731-
enum eol eol_attr = EOL_UNSET;
732-
int ident = 0, ret = 0;
748+
int ret = 0;
733749
const char *filter = NULL;
750+
struct conv_attrs ca;
734751

735-
setup_convert_check(check);
736-
if (!git_checkattr(path, ARRAY_SIZE(check), check)) {
737-
struct convert_driver *drv;
738-
crlf_action = git_path_check_crlf(path, check + 4);
739-
if (crlf_action == CRLF_GUESS)
740-
crlf_action = git_path_check_crlf(path, check + 0);
741-
ident = git_path_check_ident(path, check + 1);
742-
drv = git_path_check_convert(path, check + 2);
743-
eol_attr = git_path_check_eol(path, check + 3);
744-
if (drv && drv->clean)
745-
filter = drv->clean;
746-
}
752+
convert_attrs(&ca, path);
753+
if (ca.drv)
754+
filter = ca.drv->clean;
747755

748756
ret |= apply_filter(path, src, len, dst, filter);
749757
if (ret) {
750758
src = dst->buf;
751759
len = dst->len;
752760
}
753-
crlf_action = input_crlf_action(crlf_action, eol_attr);
754-
ret |= crlf_to_git(path, src, len, dst, crlf_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);
755763
if (ret) {
756764
src = dst->buf;
757765
len = dst->len;
758766
}
759-
return ret | ident_to_git(path, src, len, dst, ident);
767+
return ret | ident_to_git(path, src, len, dst, ca.ident);
760768
}
761769

762770
static int convert_to_working_tree_internal(const char *path, const char *src,
763771
size_t len, struct strbuf *dst,
764772
int normalizing)
765773
{
766-
struct git_attr_check check[NUM_CONV_ATTRS];
767-
enum crlf_action crlf_action = CRLF_GUESS;
768-
enum eol eol_attr = EOL_UNSET;
769-
int ident = 0, ret = 0;
774+
int ret = 0;
770775
const char *filter = NULL;
776+
struct conv_attrs ca;
771777

772-
setup_convert_check(check);
773-
if (!git_checkattr(path, ARRAY_SIZE(check), check)) {
774-
struct convert_driver *drv;
775-
crlf_action = git_path_check_crlf(path, check + 4);
776-
if (crlf_action == CRLF_GUESS)
777-
crlf_action = git_path_check_crlf(path, check + 0);
778-
ident = git_path_check_ident(path, check + 1);
779-
drv = git_path_check_convert(path, check + 2);
780-
eol_attr = git_path_check_eol(path, check + 3);
781-
if (drv && drv->smudge)
782-
filter = drv->smudge;
783-
}
778+
convert_attrs(&ca, path);
779+
if (ca.drv)
780+
filter = ca.drv->smudge;
784781

785-
ret |= ident_to_worktree(path, src, len, dst, ident);
782+
ret |= ident_to_worktree(path, src, len, dst, ca.ident);
786783
if (ret) {
787784
src = dst->buf;
788785
len = dst->len;
@@ -792,8 +789,8 @@ static int convert_to_working_tree_internal(const char *path, const char *src,
792789
* is a smudge filter. The filter might expect CRLFs.
793790
*/
794791
if (filter || !normalizing) {
795-
crlf_action = input_crlf_action(crlf_action, eol_attr);
796-
ret |= crlf_to_worktree(path, src, len, dst, crlf_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);
797794
if (ret) {
798795
src = dst->buf;
799796
len = dst->len;

0 commit comments

Comments
 (0)