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;