git-multimail: update to release 1.3.0
[gitweb.git] / strbuf.c
index d76f0aed85c4ec6eafdcfd1a8ee2b22d3d20df96..2c08dbb15381351ede663c1d41ebf3b6838a0c12 100644 (file)
--- a/strbuf.c
+++ b/strbuf.c
@@ -384,6 +384,17 @@ ssize_t strbuf_read(struct strbuf *sb, int fd, size_t hint)
        return sb->len - oldlen;
 }
 
+ssize_t strbuf_read_once(struct strbuf *sb, int fd, size_t hint)
+{
+       ssize_t cnt;
+
+       strbuf_grow(sb, hint ? hint : 8192);
+       cnt = xread(fd, sb->buf + sb->len, sb->alloc - sb->len - 1);
+       if (cnt > 0)
+               strbuf_setlen(sb, sb->len + cnt);
+       return cnt;
+}
+
 #define STRBUF_MAXLINK (2*PATH_MAX)
 
 int strbuf_readlink(struct strbuf *sb, const char *path, size_t hint)
@@ -470,9 +481,15 @@ int strbuf_getwholeline(struct strbuf *sb, FILE *fp, int term)
        if (errno == ENOMEM)
                die("Out of memory, getdelim failed");
 
-       /* Restore slopbuf that we moved out of the way before */
+       /*
+        * Restore strbuf invariants; if getdelim left us with a NULL pointer,
+        * we can just re-init, but otherwise we should make sure that our
+        * length is empty, and that the result is NUL-terminated.
+        */
        if (!sb->buf)
                strbuf_init(sb, 0);
+       else
+               strbuf_reset(sb);
        return EOF;
 }
 #else
@@ -501,15 +518,37 @@ int strbuf_getwholeline(struct strbuf *sb, FILE *fp, int term)
 }
 #endif
 
-int strbuf_getline(struct strbuf *sb, FILE *fp, int term)
+static int strbuf_getdelim(struct strbuf *sb, FILE *fp, int term)
 {
        if (strbuf_getwholeline(sb, fp, term))
                return EOF;
-       if (sb->buf[sb->len-1] == term)
-               strbuf_setlen(sb, sb->len-1);
+       if (sb->buf[sb->len - 1] == term)
+               strbuf_setlen(sb, sb->len - 1);
        return 0;
 }
 
+int strbuf_getline(struct strbuf *sb, FILE *fp)
+{
+       if (strbuf_getwholeline(sb, fp, '\n'))
+               return EOF;
+       if (sb->buf[sb->len - 1] == '\n') {
+               strbuf_setlen(sb, sb->len - 1);
+               if (sb->len && sb->buf[sb->len - 1] == '\r')
+                       strbuf_setlen(sb, sb->len - 1);
+       }
+       return 0;
+}
+
+int strbuf_getline_lf(struct strbuf *sb, FILE *fp)
+{
+       return strbuf_getdelim(sb, fp, '\n');
+}
+
+int strbuf_getline_nul(struct strbuf *sb, FILE *fp)
+{
+       return strbuf_getdelim(sb, fp, '\0');
+}
+
 int strbuf_getwholeline_fd(struct strbuf *sb, int fd, int term)
 {
        strbuf_reset(sb);
@@ -685,7 +724,7 @@ char *xstrdup_tolower(const char *string)
        size_t len, i;
 
        len = strlen(string);
-       result = xmalloc(len + 1);
+       result = xmallocz(len);
        for (i = 0; i < len; i++)
                result[i] = tolower(string[i]);
        result[i] = '\0';