Merge branch 'rs/pp-user-info-without-extra-allocation'
[gitweb.git] / strbuf.c
index 05d0693eba1eba4e2f21057388368c0890e668fe..1170d01c4322b494cd900853279766edd030de32 100644 (file)
--- a/strbuf.c
+++ b/strbuf.c
@@ -204,6 +204,54 @@ void strbuf_addf(struct strbuf *sb, const char *fmt, ...)
        va_end(ap);
 }
 
+static void add_lines(struct strbuf *out,
+                       const char *prefix1,
+                       const char *prefix2,
+                       const char *buf, size_t size)
+{
+       while (size) {
+               const char *prefix;
+               const char *next = memchr(buf, '\n', size);
+               next = next ? (next + 1) : (buf + size);
+
+               prefix = (prefix2 && buf[0] == '\n') ? prefix2 : prefix1;
+               strbuf_addstr(out, prefix);
+               strbuf_add(out, buf, next - buf);
+               size -= next - buf;
+               buf = next;
+       }
+       strbuf_complete_line(out);
+}
+
+void strbuf_add_commented_lines(struct strbuf *out, const char *buf, size_t size)
+{
+       static char prefix1[3];
+       static char prefix2[2];
+
+       if (prefix1[0] != comment_line_char) {
+               sprintf(prefix1, "%c ", comment_line_char);
+               sprintf(prefix2, "%c", comment_line_char);
+       }
+       add_lines(out, prefix1, prefix2, buf, size);
+}
+
+void strbuf_commented_addf(struct strbuf *sb, const char *fmt, ...)
+{
+       va_list params;
+       struct strbuf buf = STRBUF_INIT;
+       int incomplete_line = sb->len && sb->buf[sb->len - 1] != '\n';
+
+       va_start(params, fmt);
+       strbuf_vaddf(&buf, fmt, params);
+       va_end(params);
+
+       strbuf_add_commented_lines(sb, buf.buf, buf.len);
+       if (incomplete_line)
+               sb->buf[--sb->len] = '\0';
+
+       strbuf_release(&buf);
+}
+
 void strbuf_vaddf(struct strbuf *sb, const char *fmt, va_list ap)
 {
        int len;
@@ -414,15 +462,33 @@ int strbuf_read_file(struct strbuf *sb, const char *path, size_t hint)
 void strbuf_add_lines(struct strbuf *out, const char *prefix,
                      const char *buf, size_t size)
 {
-       while (size) {
-               const char *next = memchr(buf, '\n', size);
-               next = next ? (next + 1) : (buf + size);
-               strbuf_addstr(out, prefix);
-               strbuf_add(out, buf, next - buf);
-               size -= next - buf;
-               buf = next;
+       add_lines(out, prefix, NULL, buf, size);
+}
+
+void strbuf_addstr_xml_quoted(struct strbuf *buf, const char *s)
+{
+       while (*s) {
+               size_t len = strcspn(s, "\"<>&");
+               strbuf_add(buf, s, len);
+               s += len;
+               switch (*s) {
+               case '"':
+                       strbuf_addstr(buf, "&quot;");
+                       break;
+               case '<':
+                       strbuf_addstr(buf, "&lt;");
+                       break;
+               case '>':
+                       strbuf_addstr(buf, "&gt;");
+                       break;
+               case '&':
+                       strbuf_addstr(buf, "&amp;");
+                       break;
+               case 0:
+                       return;
+               }
+               s++;
        }
-       strbuf_complete_line(out);
 }
 
 static int is_rfc3986_reserved(char ch)
@@ -462,6 +528,25 @@ void strbuf_addstr_urlencode(struct strbuf *sb, const char *s,
        strbuf_add_urlencode(sb, s, strlen(s), reserved);
 }
 
+void strbuf_humanise_bytes(struct strbuf *buf, off_t bytes)
+{
+       if (bytes > 1 << 30) {
+               strbuf_addf(buf, "%u.%2.2u GiB",
+                           (int)(bytes >> 30),
+                           (int)(bytes & ((1 << 30) - 1)) / 10737419);
+       } else if (bytes > 1 << 20) {
+               int x = bytes + 5243;  /* for rounding */
+               strbuf_addf(buf, "%u.%2.2u MiB",
+                           x >> 20, ((x & ((1 << 20) - 1)) * 100) >> 20);
+       } else if (bytes > 1 << 10) {
+               int x = bytes + 5;  /* for rounding */
+               strbuf_addf(buf, "%u.%2.2u KiB",
+                           x >> 10, ((x & ((1 << 10) - 1)) * 100) >> 10);
+       } else {
+               strbuf_addf(buf, "%u bytes", (int)bytes);
+       }
+}
+
 int printf_ln(const char *fmt, ...)
 {
        int ret;