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 <gitster@pobox.com>

Junio C Hamano committed May 9, 2011 at 13:58 UTC 3bfba20dae16384cb7112268462bd01d30d4a698
1 file changed +38 -41
convert.c
+38 -41
@@ -703,12 +703,19 @@ static enum crlf_action input_crlf_action(enum crlf_action text_attr, enum eol e
703 return text_attr;
704 }
705
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
711 -static void setup_convert_check(struct git_attr_check *check)
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];
@@ -719,70 +726,60 @@ static void setup_convert_check(struct git_attr_check *check)
726 user_convert_tail = &user_convert;
727 git_config(read_convert_config, NULL);
728 }
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 + }
743 }
744
745 int convert_to_git(const char *path, const char *src, size_t len,
746 struct strbuf *dst, enum safe_crlf checksafe)
747 {
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;
749 const char *filter = NULL;
750 + struct conv_attrs ca;
751
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;
755
756 ret |= apply_filter(path, src, len, dst, filter);
757 if (ret) {
758 src = dst->buf;
759 len = dst->len;
760 }
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);
763 if (ret) {
764 src = dst->buf;
765 len = dst->len;
766 }
759 - return ret | ident_to_git(path, src, len, dst, ident);
767 + return ret | ident_to_git(path, src, len, dst, ca.ident);
768 }
769
770 static int convert_to_working_tree_internal(const char *path, const char *src,
771 size_t len, struct strbuf *dst,
772 int normalizing)
773 {
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;
775 const char *filter = NULL;
776 + struct conv_attrs ca;
777
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;
781
785 - ret |= ident_to_worktree(path, src, len, dst, ident);
782 + ret |= ident_to_worktree(path, src, len, dst, ca.ident);
783 if (ret) {
784 src = dst->buf;
785 len = dst->len;
@@ -792,8 +789,8 @@ static int convert_to_working_tree_internal(const char *path, const char *src,
789 * is a smudge filter. The filter might expect CRLFs.
790 */
791 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);
794 if (ret) {
795 src = dst->buf;
796 len = dst->len;