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
;