summaryrefslogtreecommitdiff
path: root/src/buffer.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/buffer.c')
-rw-r--r--src/buffer.c105
1 files changed, 62 insertions, 43 deletions
diff --git a/src/buffer.c b/src/buffer.c
index 3098f6d68..0785b5399 100644
--- a/src/buffer.c
+++ b/src/buffer.c
@@ -17,8 +17,8 @@ char git_buf_initbuf[1];
static char git_buf__oom;
#define ENSURE_SIZE(b, d) \
- if ((d) > buf->asize && git_buf_grow(b, (d)) < GIT_SUCCESS)\
- return GIT_ENOMEM;
+ if ((d) > buf->asize && git_buf_grow(b, (d)) < 0)\
+ return -1;
void git_buf_init(git_buf *buf, size_t initial_size)
@@ -34,10 +34,8 @@ void git_buf_init(git_buf *buf, size_t initial_size)
int git_buf_grow(git_buf *buf, size_t target_size)
{
int error = git_buf_try_grow(buf, target_size);
- if (error != GIT_SUCCESS) {
+ if (error != 0)
buf->ptr = &git_buf__oom;
- }
-
return error;
}
@@ -47,10 +45,10 @@ int git_buf_try_grow(git_buf *buf, size_t target_size)
size_t new_size;
if (buf->ptr == &git_buf__oom)
- return GIT_ENOMEM;
+ return -1;
if (target_size <= buf->asize)
- return GIT_SUCCESS;
+ return 0;
if (buf->asize == 0) {
new_size = target_size;
@@ -70,7 +68,7 @@ int git_buf_try_grow(git_buf *buf, size_t target_size)
new_ptr = git__realloc(new_ptr, new_size);
if (!new_ptr)
- return GIT_ENOMEM;
+ return -1;
buf->asize = new_size;
buf->ptr = new_ptr;
@@ -80,7 +78,7 @@ int git_buf_try_grow(git_buf *buf, size_t target_size)
buf->size = buf->asize - 1;
buf->ptr[buf->size] = '\0';
- return GIT_SUCCESS;
+ return 0;
}
void git_buf_free(git_buf *buf)
@@ -100,16 +98,11 @@ void git_buf_clear(git_buf *buf)
buf->ptr[0] = '\0';
}
-int git_buf_oom(const git_buf *buf)
+bool git_buf_oom(const git_buf *buf)
{
return (buf->ptr == &git_buf__oom);
}
-int git_buf_lasterror(const git_buf *buf)
-{
- return (buf->ptr == &git_buf__oom) ? GIT_ENOMEM : GIT_SUCCESS;
-}
-
int git_buf_set(git_buf *buf, const char *data, size_t len)
{
if (len == 0 || data == NULL) {
@@ -122,7 +115,7 @@ int git_buf_set(git_buf *buf, const char *data, size_t len)
buf->size = len;
buf->ptr[buf->size] = '\0';
}
- return GIT_SUCCESS;
+ return 0;
}
int git_buf_sets(git_buf *buf, const char *string)
@@ -135,7 +128,7 @@ int git_buf_putc(git_buf *buf, char c)
ENSURE_SIZE(buf, buf->size + 2);
buf->ptr[buf->size++] = c;
buf->ptr[buf->size] = '\0';
- return GIT_SUCCESS;
+ return 0;
}
int git_buf_put(git_buf *buf, const char *data, size_t len)
@@ -144,7 +137,7 @@ int git_buf_put(git_buf *buf, const char *data, size_t len)
memmove(buf->ptr + buf->size, data, len);
buf->size += len;
buf->ptr[buf->size] = '\0';
- return GIT_SUCCESS;
+ return 0;
}
int git_buf_puts(git_buf *buf, const char *string)
@@ -153,22 +146,26 @@ int git_buf_puts(git_buf *buf, const char *string)
return git_buf_put(buf, string, strlen(string));
}
-int git_buf_printf(git_buf *buf, const char *format, ...)
+int git_buf_vprintf(git_buf *buf, const char *format, va_list ap)
{
int len;
- va_list arglist;
- ENSURE_SIZE(buf, buf->size + 1);
+ ENSURE_SIZE(buf, buf->size + (strlen(format) * 2));
while (1) {
- va_start(arglist, format);
- len = p_vsnprintf(buf->ptr + buf->size, buf->asize - buf->size, format, arglist);
- va_end(arglist);
+ va_list args;
+ va_copy(args, ap);
+
+ len = p_vsnprintf(
+ buf->ptr + buf->size,
+ buf->asize - buf->size,
+ format, args
+ );
if (len < 0) {
- free(buf->ptr);
+ git__free(buf->ptr);
buf->ptr = &git_buf__oom;
- return GIT_ENOMEM;
+ return -1;
}
if ((size_t)len + 1 <= buf->asize - buf->size) {
@@ -179,7 +176,19 @@ int git_buf_printf(git_buf *buf, const char *format, ...)
ENSURE_SIZE(buf, buf->size + len + 1);
}
- return GIT_SUCCESS;
+ return 0;
+}
+
+int git_buf_printf(git_buf *buf, const char *format, ...)
+{
+ int r;
+ va_list ap;
+
+ va_start(ap, format);
+ r = git_buf_vprintf(buf, format, ap);
+ va_end(ap);
+
+ return r;
}
void git_buf_copy_cstr(char *data, size_t datasize, const git_buf *buf)
@@ -220,8 +229,8 @@ void git_buf_truncate(git_buf *buf, size_t len)
void git_buf_rtruncate_at_char(git_buf *buf, char separator)
{
- int idx = git_buf_rfind_next(buf, separator);
- git_buf_truncate(buf, idx < 0 ? 0 : idx);
+ ssize_t idx = git_buf_rfind_next(buf, separator);
+ git_buf_truncate(buf, idx < 0 ? 0 : (size_t)idx);
}
void git_buf_swap(git_buf *buf_a, git_buf *buf_b)
@@ -262,9 +271,9 @@ void git_buf_attach(git_buf *buf, char *ptr, size_t asize)
int git_buf_join_n(git_buf *buf, char separator, int nbuf, ...)
{
va_list ap;
- int i, error = GIT_SUCCESS;
- size_t total_size = 0;
- char *out;
+ int i;
+ size_t total_size = 0, original_size = buf->size;
+ char *out, *original = buf->ptr;
if (buf->size > 0 && buf->ptr[buf->size - 1] != separator)
++total_size; /* space for initial separator */
@@ -288,9 +297,10 @@ int git_buf_join_n(git_buf *buf, char separator, int nbuf, ...)
va_end(ap);
/* expand buffer if needed */
- if (total_size > 0 &&
- (error = git_buf_grow(buf, buf->size + total_size + 1)) < GIT_SUCCESS)
- return error;
+ if (total_size == 0)
+ return 0;
+ if (git_buf_grow(buf, buf->size + total_size + 1) < 0)
+ return -1;
out = buf->ptr + buf->size;
@@ -307,12 +317,23 @@ int git_buf_join_n(git_buf *buf, char separator, int nbuf, ...)
if (!segment)
continue;
+ /* deal with join that references buffer's original content */
+ if (segment >= original && segment < original + original_size) {
+ size_t offset = (segment - original);
+ segment = buf->ptr + offset;
+ segment_len = original_size - offset;
+ } else {
+ segment_len = strlen(segment);
+ }
+
/* skip leading separators */
if (out > buf->ptr && out[-1] == separator)
- while (*segment == separator) segment++;
+ while (segment_len > 0 && *segment == separator) {
+ segment++;
+ segment_len--;
+ }
/* copy over next buffer */
- segment_len = strlen(segment);
if (segment_len > 0) {
memmove(out, segment, segment_len);
out += segment_len;
@@ -328,7 +349,7 @@ int git_buf_join_n(git_buf *buf, char separator, int nbuf, ...)
buf->size = out - buf->ptr;
buf->ptr[buf->size] = '\0';
- return error;
+ return 0;
}
int git_buf_join(
@@ -337,7 +358,6 @@ int git_buf_join(
const char *str_a,
const char *str_b)
{
- int error = GIT_SUCCESS;
size_t strlen_a = str_a ? strlen(str_a) : 0;
size_t strlen_b = strlen(str_b);
int need_sep = 0;
@@ -357,9 +377,8 @@ int git_buf_join(
if (str_a >= buf->ptr && str_a < buf->ptr + buf->size)
offset_a = str_a - buf->ptr;
- error = git_buf_grow(buf, strlen_a + strlen_b + need_sep + 1);
- if (error < GIT_SUCCESS)
- return error;
+ if (git_buf_grow(buf, strlen_a + strlen_b + need_sep + 1) < 0)
+ return -1;
/* fix up internal pointers */
if (offset_a >= 0)
@@ -375,7 +394,7 @@ int git_buf_join(
buf->size = strlen_a + strlen_b + need_sep;
buf->ptr[buf->size] = '\0';
- return error;
+ return 0;
}
void git_buf_rtrim(git_buf *buf)