]>
git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/blob - tools/perf/util/strbuf.c
3 #include <linux/kernel.h>
7 * Used as the default ->buf value, so that people can always assume
8 * buf is non NULL and ->buf is NUL terminated even for a freshly
11 char strbuf_slopbuf
[1];
13 int strbuf_init(struct strbuf
*sb
, ssize_t hint
)
15 sb
->alloc
= sb
->len
= 0;
16 sb
->buf
= strbuf_slopbuf
;
18 return strbuf_grow(sb
, hint
);
22 void strbuf_release(struct strbuf
*sb
)
30 char *strbuf_detach(struct strbuf
*sb
, size_t *sz
)
32 char *res
= sb
->alloc
? sb
->buf
: NULL
;
39 int strbuf_grow(struct strbuf
*sb
, size_t extra
)
42 size_t nr
= sb
->len
+ extra
+ 1;
50 if (alloc_nr(sb
->alloc
) > nr
)
51 nr
= alloc_nr(sb
->alloc
);
54 * Note that sb->buf == strbuf_slopbuf if sb->alloc == 0, and it is
55 * a static variable. Thus we have to avoid passing it to realloc.
57 buf
= realloc(sb
->alloc
? sb
->buf
: NULL
, nr
* sizeof(*buf
));
66 int strbuf_addch(struct strbuf
*sb
, int c
)
68 int ret
= strbuf_grow(sb
, 1);
72 sb
->buf
[sb
->len
++] = c
;
73 sb
->buf
[sb
->len
] = '\0';
77 int strbuf_add(struct strbuf
*sb
, const void *data
, size_t len
)
79 int ret
= strbuf_grow(sb
, len
);
83 memcpy(sb
->buf
+ sb
->len
, data
, len
);
84 return strbuf_setlen(sb
, sb
->len
+ len
);
87 static int strbuf_addv(struct strbuf
*sb
, const char *fmt
, va_list ap
)
92 if (!strbuf_avail(sb
)) {
93 ret
= strbuf_grow(sb
, 64);
98 va_copy(ap_saved
, ap
);
99 len
= vsnprintf(sb
->buf
+ sb
->len
, sb
->alloc
- sb
->len
, fmt
, ap
);
102 if (len
> strbuf_avail(sb
)) {
103 ret
= strbuf_grow(sb
, len
);
106 len
= vsnprintf(sb
->buf
+ sb
->len
, sb
->alloc
- sb
->len
, fmt
, ap_saved
);
108 if (len
> strbuf_avail(sb
)) {
109 pr_debug("this should not happen, your vsnprintf is broken");
113 return strbuf_setlen(sb
, sb
->len
+ len
);
116 int strbuf_addf(struct strbuf
*sb
, const char *fmt
, ...)
122 ret
= strbuf_addv(sb
, fmt
, ap
);
127 ssize_t
strbuf_read(struct strbuf
*sb
, int fd
, ssize_t hint
)
129 size_t oldlen
= sb
->len
;
130 size_t oldalloc
= sb
->alloc
;
133 ret
= strbuf_grow(sb
, hint
? hint
: 8192);
140 cnt
= read(fd
, sb
->buf
+ sb
->len
, sb
->alloc
- sb
->len
- 1);
145 strbuf_setlen(sb
, oldlen
);
151 ret
= strbuf_grow(sb
, 8192);
156 sb
->buf
[sb
->len
] = '\0';
157 return sb
->len
- oldlen
;