contrib/hooks/post-receive-email: fix typo
[gitweb.git] / strbuf.c
index dcb725dcdd2f8edb04502fed425bd3b7a7204ebf..f4201e160de2ccb9f2d9adef695c73a124e676d5 100644 (file)
--- a/strbuf.c
+++ b/strbuf.c
@@ -1,27 +1,33 @@
 #include "cache.h"
 
+/*
+ * Used as the default ->buf value, so that people can always assume
+ * buf is non NULL and ->buf is NUL terminated even for a freshly
+ * initialized strbuf.
+ */
+char strbuf_slopbuf[1];
+
 void strbuf_init(struct strbuf *sb, size_t hint)
 {
-       memset(sb, 0, sizeof(*sb));
+       sb->alloc = sb->len = 0;
+       sb->buf = strbuf_slopbuf;
        if (hint)
                strbuf_grow(sb, hint);
 }
 
 void strbuf_release(struct strbuf *sb)
 {
-       free(sb->buf);
-       memset(sb, 0, sizeof(*sb));
-}
-
-void strbuf_reset(struct strbuf *sb)
-{
-       if (sb->len)
-               strbuf_setlen(sb, 0);
+       if (sb->alloc) {
+               free(sb->buf);
+               strbuf_init(sb, 0);
+       }
 }
 
-char *strbuf_detach(struct strbuf *sb)
+char *strbuf_detach(struct strbuf *sb, size_t *sz)
 {
-       char *res = sb->buf;
+       char *res = sb->alloc ? sb->buf : NULL;
+       if (sz)
+               *sz = sb->len;
        strbuf_init(sb, 0);
        return res;
 }
@@ -40,6 +46,8 @@ void strbuf_grow(struct strbuf *sb, size_t extra)
 {
        if (sb->len + extra + 1 <= sb->len)
                die("you want to use way too much memory");
+       if (!sb->alloc)
+               sb->buf = NULL;
        ALLOC_GROW(sb->buf, sb->len + extra + 1, sb->alloc);
 }
 
@@ -50,6 +58,18 @@ void strbuf_rtrim(struct strbuf *sb)
        sb->buf[sb->len] = '\0';
 }
 
+int strbuf_cmp(struct strbuf *a, struct strbuf *b)
+{
+       int cmp;
+       if (a->len < b->len) {
+               cmp = memcmp(a->buf, b->buf, a->len);
+               return cmp ? cmp : -1;
+       } else {
+               cmp = memcmp(a->buf, b->buf, b->len);
+               return cmp ? cmp : a->len != b->len;
+       }
+}
+
 void strbuf_splice(struct strbuf *sb, size_t pos, size_t len,
                                   const void *data, size_t dlen)
 {
@@ -165,3 +185,18 @@ int strbuf_getline(struct strbuf *sb, FILE *fp, int term)
        sb->buf[sb->len] = '\0';
        return 0;
 }
+
+int strbuf_read_file(struct strbuf *sb, const char *path, size_t hint)
+{
+       int fd, len;
+
+       fd = open(path, O_RDONLY);
+       if (fd < 0)
+               return -1;
+       len = strbuf_read(sb, fd, hint);
+       close(fd);
+       if (len < 0)
+               return -1;
+
+       return len;
+}