filter: Load attributes for file
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173
diff --git a/src/filter.c b/src/filter.c
index b97ac66..1775c09 100644
--- a/src/filter.c
+++ b/src/filter.c
@@ -10,6 +10,8 @@
#include "hash.h"
#include "filter.h"
+#include "git2/attr.h"
+
/* Fresh from Core Git. I wonder what we could use this for... */
void git_text__stat(git_text_stats *stats, git_buf *text)
{
@@ -130,3 +132,89 @@ int git_filter__apply(git_buf *dest, git_buf *source, git_vector *filters, const
return GIT_SUCCESS;
}
+
+
+static int check_crlf(const char *value)
+{
+ if (value == git_attr__true)
+ return GIT_CRLF_TEXT;
+
+ if (value == git_attr__false)
+ return GIT_CRLF_BINARY;
+
+ if (value == NULL)
+ return GIT_CRLF_GUESS;
+
+ if (strcmp(value, "input") == 0)
+ return GIT_CRLF_INPUT;
+
+ if (strcmp(value, "auto") == 0)
+ return GIT_CRLF_AUTO;
+
+ return GIT_CRLF_GUESS;
+}
+
+static int check_eol(const char *value)
+{
+ if (value == NULL)
+ return GIT_EOL_UNSET;
+
+ if (strcmp(value, "lf") == 0)
+ return GIT_EOL_LF;
+
+ if (strcmp(value, "crlf") == 0)
+ return GIT_EOL_CRLF;
+
+ return GIT_EOL_UNSET;
+}
+
+static int check_ident(const char *value)
+{
+ return (value == git_attr__true);
+}
+
+#if 0
+static int input_crlf_action(enum crlf_action text_attr, enum eol eol_attr)
+{
+ if (text_attr == CRLF_BINARY)
+ return CRLF_BINARY;
+ if (eol_attr == EOL_LF)
+ return CRLF_INPUT;
+ if (eol_attr == EOL_CRLF)
+ return CRLF_CRLF;
+ return text_attr;
+}
+#endif
+
+int git_filter__load_attrs(git_conv_attrs *ca, git_repository *repo, const char *path)
+{
+#define NUM_CONV_ATTRS 5
+
+ static const char *attr_names[NUM_CONV_ATTRS] = {
+ "crlf", "ident", "filter", "eol", "text",
+ };
+
+ const char *attr_vals[NUM_CONV_ATTRS];
+ int error;
+
+ error = git_attr_get_many(repo, path, NUM_CONV_ATTRS, attr_names, attr_vals);
+
+ if (error == GIT_ENOTFOUND) {
+ ca->crlf_action = GIT_CRLF_GUESS;
+ ca->eol_attr = GIT_EOL_UNSET;
+ ca->ident = 0;
+ return 0;
+ }
+
+ if (error == GIT_SUCCESS) {
+ ca->crlf_action = check_crlf(attr_vals[4]); /* text */
+ if (ca->crlf_action == GIT_CRLF_GUESS)
+ ca->crlf_action = check_crlf(attr_vals[0]); /* clrf */
+
+ ca->ident = check_ident(attr_vals[1]); /* ident */
+ ca->eol_attr = check_eol(attr_vals[3]); /* eol */
+ return 0;
+ }
+
+ return error;
+}
diff --git a/src/filter.h b/src/filter.h
index 9a8f849..2ed9da0 100644
--- a/src/filter.h
+++ b/src/filter.h
@@ -19,6 +19,41 @@ typedef enum {
GIT_FILTER_TO_ODB
} git_filter_mode;
+typedef enum {
+ GIT_CRLF_GUESS = -1,
+ GIT_CRLF_BINARY = 0,
+ GIT_CRLF_TEXT,
+ GIT_CRLF_INPUT,
+ GIT_CRLF_CRLF,
+ GIT_CRLF_AUTO,
+
+ GIT_SAFE_CRLF_FALSE = 0,
+ GIT_SAFE_CRLF_FAIL = 1,
+ GIT_SAFE_CRLF_WARN = 2,
+
+ GIT_AUTO_CRLF_FALSE = 0,
+ GIT_AUTO_CRLF_TRUE = 1,
+ GIT_AUTO_CRLF_INPUT = -1,
+} git_crlf_t;
+
+typedef enum {
+ GIT_EOL_UNSET,
+ GIT_EOL_CRLF,
+ GIT_EOL_LF,
+#ifdef GIT_WIN32
+ GIT_EOL_NATIVE = GIT_EOL_CRLF
+#else
+ GIT_EOL_NATIVE = GIT_EOL_LF
+#endif
+} git_eol_t;
+
+
+typedef struct {
+ int crlf_action;
+ int eol_attr;
+ int ident;
+} git_conv_attrs;
+
typedef struct {
/* NUL, CR, LF and CRLF counts */
unsigned int nul, cr, lf, crlf;
@@ -28,6 +63,7 @@ typedef struct {
} git_text_stats;
extern int git_filter__load_for_file(git_vector *filters, git_repository *repo, const char *full_path, int mode);
+extern int git_filter__load_attrs(git_conv_attrs *ca, git_repository *repo, const char *path);
extern int git_filter__apply(git_buf *dest, git_buf *source, git_vector *filters, const char *filename);
/* Gather stats for a piece of text */
diff --git a/src/repository.h b/src/repository.h
index 516fd10..fa19d2e 100644
--- a/src/repository.h
+++ b/src/repository.h
@@ -46,6 +46,11 @@ struct git_repository {
unsigned is_bare:1;
unsigned int lru_counter;
+
+ struct {
+ int core_eol;
+ int auto_crlf;
+ } filter_options;
};
/* fully free the object; internal method, do not