Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/libgit2.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBen Straub <bstraub@github.com>2012-08-01 02:38:12 +0400
committerBen Straub <bstraub@github.com>2012-08-01 02:38:12 +0400
commite4bac3c4692834e6d0ca607aca229ddcae0ba2b7 (patch)
treef92323cd67cfadb1f412742e03644ff73cc2a009 /src/crlf.c
parent8e4aae1ae5f9f023641ab4046dfee6c744e58e13 (diff)
Checkout: crlf filter.
Diffstat (limited to 'src/crlf.c')
-rw-r--r--src/crlf.c88
1 files changed, 80 insertions, 8 deletions
diff --git a/src/crlf.c b/src/crlf.c
index f68938e61..509e55897 100644
--- a/src/crlf.c
+++ b/src/crlf.c
@@ -184,6 +184,85 @@ static int crlf_apply_to_odb(git_filter *self, git_buf *dest, const git_buf *sou
return drop_crlf(dest, source);
}
+static int convert_line_endings(git_buf *dest, const git_buf *source, const char *ending)
+{
+ const char *scan = git_buf_cstr(source),
+ *next,
+ *scan_end = git_buf_cstr(source) + git_buf_len(source);
+
+ while ((next = memchr(scan, '\n', scan_end - scan)) != NULL) {
+ if (next > scan)
+ git_buf_put(dest, scan, next-scan);
+ git_buf_puts(dest, ending);
+ scan = next + 1;
+ }
+
+ git_buf_put(dest, scan, scan_end - scan);
+ return 0;
+}
+
+static const char *line_ending(struct crlf_filter *filter)
+{
+ switch (filter->attrs.crlf_action) {
+ case GIT_CRLF_BINARY:
+ case GIT_CRLF_INPUT:
+ return "\n";
+
+ case GIT_CRLF_CRLF:
+ return "\r\n";
+
+ case GIT_CRLF_AUTO:
+ case GIT_CRLF_TEXT:
+ case GIT_CRLF_GUESS:
+ break;
+
+ default:
+ goto line_ending_error;
+ }
+
+ switch (filter->attrs.eol) {
+ case GIT_EOL_UNSET:
+ return GIT_EOL_NATIVE == GIT_EOL_CRLF
+ ? "\r\n"
+ : "\n";
+
+ case GIT_EOL_CRLF:
+ return "\r\n";
+
+ case GIT_EOL_LF:
+ return "\n";
+
+ default:
+ goto line_ending_error;
+ }
+
+line_ending_error:
+ giterr_set(GITERR_INVALID, "Invalid input to line ending filter");
+ return NULL;
+}
+
+static int crlf_apply_to_workdir(git_filter *self, git_buf *dest, const git_buf *source)
+{
+ struct crlf_filter *filter = (struct crlf_filter *)self;
+ const char *workdir_ending = NULL;
+
+ assert (self && dest && source);
+
+ /* Empty file? Nothing to do. */
+ if (git_buf_len(source) == 0)
+ return 0;
+
+ /* Determine proper line ending */
+ workdir_ending = line_ending(filter);
+ if (!workdir_ending) return -1;
+
+ /* If the line ending is '\n', just copy the input */
+ if (!strcmp(workdir_ending, "\n"))
+ return git_buf_puts(dest, git_buf_cstr(source));
+
+ return convert_line_endings(dest, source, workdir_ending);
+}
+
static int find_and_add_filter(git_vector *filters, git_repository *repo, const char *path,
int (*apply)(struct git_filter *self, git_buf *dest, const git_buf *source))
{
@@ -207,8 +286,7 @@ static int find_and_add_filter(git_vector *filters, git_repository *repo, const
if (ca.crlf_action == GIT_CRLF_GUESS) {
int auto_crlf;
- if ((error = git_repository__cvar(
- &auto_crlf, repo, GIT_CVAR_AUTO_CRLF)) < 0)
+ if ((error = git_repository__cvar(&auto_crlf, repo, GIT_CVAR_AUTO_CRLF)) < 0)
return error;
if (auto_crlf == GIT_AUTO_CRLF_FALSE)
@@ -227,12 +305,6 @@ static int find_and_add_filter(git_vector *filters, git_repository *repo, const
return git_vector_insert(filters, filter);
}
-static int crlf_apply_to_workdir(git_filter *self, git_buf *dest, const git_buf *source)
-{
- /* TODO */
- return -1;
-}
-
int git_filter_add__crlf_to_odb(git_vector *filters, git_repository *repo, const char *path)
{
return find_and_add_filter(filters, repo, path, &crlf_apply_to_odb);