diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/blob.c | 6 | ||||
-rw-r--r-- | src/blob.h | 1 | ||||
-rw-r--r-- | src/buffer.c | 7 | ||||
-rw-r--r-- | src/buffer.h | 2 | ||||
-rw-r--r-- | src/crlf.c | 60 | ||||
-rw-r--r-- | src/filter.c | 31 |
6 files changed, 51 insertions, 56 deletions
diff --git a/src/blob.c b/src/blob.c index e1f4a7f6a..b67f8afa5 100644 --- a/src/blob.c +++ b/src/blob.c @@ -25,6 +25,12 @@ size_t git_blob_rawsize(git_blob *blob) return blob->odb_object->raw.len; } +int git_blob__getbuf(git_buf *buffer, git_blob *blob) +{ + return git_buf_set( + buffer, blob->odb_object->raw.data, blob->odb_object->raw.len); +} + void git_blob__free(git_blob *blob) { git_odb_object_free(blob->odb_object); diff --git a/src/blob.h b/src/blob.h index f810b506b..0305e9473 100644 --- a/src/blob.h +++ b/src/blob.h @@ -19,5 +19,6 @@ struct git_blob { void git_blob__free(git_blob *blob); int git_blob__parse(git_blob *blob, git_odb_object *obj); +int git_blob__getbuf(git_buf *buffer, git_blob *blob); #endif diff --git a/src/buffer.c b/src/buffer.c index 68cc39388..3098f6d68 100644 --- a/src/buffer.c +++ b/src/buffer.c @@ -389,3 +389,10 @@ void git_buf_rtrim(git_buf *buf) buf->ptr[buf->size] = '\0'; } + +int git_buf_cmp(const git_buf *a, const git_buf *b) +{ + int result = memcmp(a->ptr, b->ptr, min(a->size, b->size)); + return (result != 0) ? result : + (a->size < b->size) ? -1 : (a->size > b->size) ? 1 : 0; +} diff --git a/src/buffer.h b/src/buffer.h index 3e9cb1713..3cdd794af 100644 --- a/src/buffer.h +++ b/src/buffer.h @@ -118,4 +118,6 @@ GIT_INLINE(int) git_buf_rfind_next(git_buf *buf, char ch) /* Remove whitespace from the end of the buffer */ void git_buf_rtrim(git_buf *buf); +int git_buf_cmp(const git_buf *a, const git_buf *b); + #endif diff --git a/src/crlf.c b/src/crlf.c index 404156d6a..f0ec7b736 100644 --- a/src/crlf.c +++ b/src/crlf.c @@ -104,52 +104,32 @@ static int crlf_load_attributes(struct crlf_attrs *ca, git_repository *repo, con static int drop_crlf(git_buf *dest, const git_buf *source) { - size_t psize = source->size - 1; - size_t i = 0; + const char *scan = source->ptr, *next; + const char *scan_end = source->ptr + source->size; - /* Initial scan: see if we can reach the end of the document - * without finding a single carriage return */ - while (i < psize && source->ptr[i] != '\r') - i++; - - /* Clean file? Tell the library to skip this filter */ - if (i == psize) - return -1; - - /* Main scan loop. Keep moving forward until we find a carriage - * return, and then copy the whole chunk to the destination - * buffer. - * - * Note that we only scan until `size - 1`, because we cannot drop a - * carriage return if it's the last character in the file (what a weird - * file, anyway) + /* Main scan loop. Find the next carriage return and copy the + * whole chunk up to that point to the destination buffer. */ - while (i < psize) { - size_t org = i; + while ((next = memchr(scan, '\r', scan_end - scan)) != NULL) { + /* copy input up to \r */ + if (next > scan) + git_buf_put(dest, scan, next - scan); - while (i < psize && source->ptr[i] != '\r') - i++; - - if (i > org) - git_buf_put(dest, source->ptr + org, i - org); - - /* We found a carriage return. Is the next character a newline? - * If it is, we just keep moving. The newline will be copied - * to the dest in the next chunk. - * - * If it's not a newline, we need to insert the carriage return - * into the dest buffer, because we don't drop lone CRs. - */ - if (source->ptr[i + 1] != '\n') { + /* Do not drop \r unless it is followed by \n */ + if (*(next + 1) != '\n') git_buf_putc(dest, '\r'); - } - - i++; + + scan = next + 1; } - /* Copy the last character in the file */ - git_buf_putc(dest, source->ptr[psize]); - return 0; + /* If there was no \r, then tell the library to skip this filter */ + if (scan == source->ptr) + return -1; + + /* Copy remaining input into dest */ + git_buf_put(dest, scan, scan_end - scan); + + return git_buf_lasterror(dest); } static int crlf_apply_to_odb(git_filter *self, git_buf *dest, const git_buf *source) diff --git a/src/filter.c b/src/filter.c index f93730acb..f0ee1ad39 100644 --- a/src/filter.c +++ b/src/filter.c @@ -12,7 +12,7 @@ #include "repository.h" #include "git2/config.h" -/* Fresh from Core Git. I wonder what we could use this for... */ +/* Tweaked from Core Git. I wonder what we could use this for... */ void git_text_gather_stats(git_text_stats *stats, const git_buf *text) { size_t i; @@ -27,20 +27,20 @@ void git_text_gather_stats(git_text_stats *stats, const git_buf *text) if (i + 1 < text->size && text->ptr[i + 1] == '\n') stats->crlf++; - - continue; } - if (c == '\n') { + else if (c == '\n') stats->lf++; - continue; - } - if (c == 127) + else if (c == 0x85) + /* Unicode CR+LF */ + stats->crlf++; + + else if (c == 127) /* DEL */ stats->nonprintable++; - else if (c < 32) { + else if (c <= 0x1F || (c >= 0x80 && c <= 0x9F)) { switch (c) { /* BS, HT, ESC and FF */ case '\b': case '\t': case '\033': case '\014': @@ -53,6 +53,7 @@ void git_text_gather_stats(git_text_stats *stats, const git_buf *text) stats->nonprintable++; } } + else stats->printable++; } @@ -118,7 +119,7 @@ void git_filters_free(git_vector *filters) int git_filters_apply(git_buf *dest, git_buf *source, git_vector *filters) { - unsigned int src, dst, i; + unsigned int i, src; git_buf *dbuffer[2]; dbuffer[0] = source; @@ -138,28 +139,26 @@ int git_filters_apply(git_buf *dest, git_buf *source, git_vector *filters) for (i = 0; i < filters->length; ++i) { git_filter *filter = git_vector_get(filters, i); - dst = (src + 1) % 2; + unsigned int dst = 1 - src; git_buf_clear(dbuffer[dst]); - /* Apply the filter, from dbuffer[src] to dbuffer[dst]; + /* Apply the filter from dbuffer[src] to the other buffer; * if the filtering is canceled by the user mid-filter, * we skip to the next filter without changing the source * of the double buffering (so that the text goes through * cleanly). */ - if (filter->apply(filter, dbuffer[dst], dbuffer[src]) == 0) { - src = (src + 1) % 2; - } + if (filter->apply(filter, dbuffer[dst], dbuffer[src]) == 0) + src = dst; if (git_buf_oom(dbuffer[dst])) return GIT_ENOMEM; } /* Ensure that the output ends up in dbuffer[1] (i.e. the dest) */ - if (dst != 1) { + if (src != 1) git_buf_swap(dest, source); - } return GIT_SUCCESS; } |