3 #include <linux/kernel.h>
5 int prefixcmp(const char *str, const char *prefix)
7 for (; ; str++, prefix++)
10 else if (*str != *prefix)
11 return (unsigned char)*prefix - (unsigned char)*str;
15 * Used as the default ->buf value, so that people can always assume
16 * buf is non NULL and ->buf is NUL terminated even for a freshly
19 char strbuf_slopbuf[1];
21 int strbuf_init(struct strbuf *sb, ssize_t hint)
23 sb->alloc = sb->len = 0;
24 sb->buf = strbuf_slopbuf;
26 return strbuf_grow(sb, hint);
30 void strbuf_release(struct strbuf *sb)
38 char *strbuf_detach(struct strbuf *sb, size_t *sz)
40 char *res = sb->alloc ? sb->buf : NULL;
47 int strbuf_grow(struct strbuf *sb, size_t extra)
50 size_t nr = sb->len + extra + 1;
58 if (alloc_nr(sb->alloc) > nr)
59 nr = alloc_nr(sb->alloc);
62 * Note that sb->buf == strbuf_slopbuf if sb->alloc == 0, and it is
63 * a static variable. Thus we have to avoid passing it to realloc.
65 buf = realloc(sb->alloc ? sb->buf : NULL, nr * sizeof(*buf));
74 int strbuf_addch(struct strbuf *sb, int c)
76 int ret = strbuf_grow(sb, 1);
80 sb->buf[sb->len++] = c;
81 sb->buf[sb->len] = '\0';
85 int strbuf_add(struct strbuf *sb, const void *data, size_t len)
87 int ret = strbuf_grow(sb, len);
91 memcpy(sb->buf + sb->len, data, len);
92 return strbuf_setlen(sb, sb->len + len);
95 static int strbuf_addv(struct strbuf *sb, const char *fmt, va_list ap)
100 if (!strbuf_avail(sb)) {
101 ret = strbuf_grow(sb, 64);
106 va_copy(ap_saved, ap);
107 len = vsnprintf(sb->buf + sb->len, sb->alloc - sb->len, fmt, ap);
110 if (len > strbuf_avail(sb)) {
111 ret = strbuf_grow(sb, len);
114 len = vsnprintf(sb->buf + sb->len, sb->alloc - sb->len, fmt, ap_saved);
116 if (len > strbuf_avail(sb)) {
117 pr_debug("this should not happen, your vsnprintf is broken");
121 return strbuf_setlen(sb, sb->len + len);
124 int strbuf_addf(struct strbuf *sb, const char *fmt, ...)
130 ret = strbuf_addv(sb, fmt, ap);
135 ssize_t strbuf_read(struct strbuf *sb, int fd, ssize_t hint)
137 size_t oldlen = sb->len;
138 size_t oldalloc = sb->alloc;
141 ret = strbuf_grow(sb, hint ? hint : 8192);
148 cnt = read(fd, sb->buf + sb->len, sb->alloc - sb->len - 1);
153 strbuf_setlen(sb, oldlen);
159 ret = strbuf_grow(sb, 8192);
164 sb->buf[sb->len] = '\0';
165 return sb->len - oldlen;