Code

grep doc: add --break / --heading / -W to synopsis
[git.git] / strbuf.c
index a849705197a6ad3d0d2ab9de22b269de6b4fc2b1..5135d5950d9a5ea3ce8064e5491e53da17645da9 100644 (file)
--- a/strbuf.c
+++ b/strbuf.c
@@ -383,6 +383,22 @@ int strbuf_getline(struct strbuf *sb, FILE *fp, int term)
        return 0;
 }
 
+int strbuf_getwholeline_fd(struct strbuf *sb, int fd, int term)
+{
+       strbuf_reset(sb);
+
+       while (1) {
+               char ch;
+               ssize_t len = xread(fd, &ch, 1);
+               if (len <= 0)
+                       return EOF;
+               strbuf_addch(sb, ch);
+               if (ch == term)
+                       break;
+       }
+       return 0;
+}
+
 int strbuf_read_file(struct strbuf *sb, const char *path, size_t hint)
 {
        int fd, len;
@@ -411,3 +427,40 @@ void strbuf_add_lines(struct strbuf *out, const char *prefix,
        }
        strbuf_complete_line(out);
 }
+
+static int is_rfc3986_reserved(char ch)
+{
+       switch (ch) {
+               case '!': case '*': case '\'': case '(': case ')': case ';':
+               case ':': case '@': case '&': case '=': case '+': case '$':
+               case ',': case '/': case '?': case '#': case '[': case ']':
+                       return 1;
+       }
+       return 0;
+}
+
+static int is_rfc3986_unreserved(char ch)
+{
+       return isalnum(ch) ||
+               ch == '-' || ch == '_' || ch == '.' || ch == '~';
+}
+
+void strbuf_add_urlencode(struct strbuf *sb, const char *s, size_t len,
+                         int reserved)
+{
+       strbuf_grow(sb, len);
+       while (len--) {
+               char ch = *s++;
+               if (is_rfc3986_unreserved(ch) ||
+                   (!reserved && is_rfc3986_reserved(ch)))
+                       strbuf_addch(sb, ch);
+               else
+                       strbuf_addf(sb, "%%%02x", ch);
+       }
+}
+
+void strbuf_addstr_urlencode(struct strbuf *sb, const char *s,
+                            int reserved)
+{
+       strbuf_add_urlencode(sb, s, strlen(s), reserved);
+}