aboutsummaryrefslogtreecommitdiff
path: root/win32
diff options
context:
space:
mode:
authorNguyễn Thái Ngọc Duy <pclouds@gmail.com>2010-04-14 02:16:15 +0200
committerNguyễn Thái Ngọc Duy <pclouds@gmail.com>2010-04-20 19:14:20 +0200
commit340150ca84cca55bcf98ecd6dc9b951f8c74feaa (patch)
treeaccc5abb84fe5f671d6f0b13ed66df8b5acdb6df /win32
parent8aed602855bbc9a5b614515833796830a3437a98 (diff)
downloadbusybox-w32-340150ca84cca55bcf98ecd6dc9b951f8c74feaa.tar.gz
busybox-w32-340150ca84cca55bcf98ecd6dc9b951f8c74feaa.tar.bz2
busybox-w32-340150ca84cca55bcf98ecd6dc9b951f8c74feaa.zip
win32: mingw32/strbuf.c
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
Diffstat (limited to 'win32')
-rw-r--r--win32/strbuf.c352
1 files changed, 352 insertions, 0 deletions
diff --git a/win32/strbuf.c b/win32/strbuf.c
new file mode 100644
index 000000000..98659d448
--- /dev/null
+++ b/win32/strbuf.c
@@ -0,0 +1,352 @@
1#include "libbb.h"
2#include "strbuf.h"
3#include "git.h"
4
5/*
6 * Used as the default ->buf value, so that people can always assume
7 * buf is non NULL and ->buf is NUL terminated even for a freshly
8 * initialized strbuf.
9 */
10char strbuf_slopbuf[1];
11
12void strbuf_init(struct strbuf *sb, size_t hint)
13{
14 sb->alloc = sb->len = 0;
15 sb->buf = strbuf_slopbuf;
16 if (hint)
17 strbuf_grow(sb, hint);
18}
19
20void strbuf_release(struct strbuf *sb)
21{
22 if (sb->alloc) {
23 free(sb->buf);
24 strbuf_init(sb, 0);
25 }
26}
27
28char *strbuf_detach(struct strbuf *sb, size_t *sz)
29{
30 char *res = sb->alloc ? sb->buf : NULL;
31 if (sz)
32 *sz = sb->len;
33 strbuf_init(sb, 0);
34 return res;
35}
36
37void strbuf_attach(struct strbuf *sb, void *buf, size_t len, size_t alloc)
38{
39 strbuf_release(sb);
40 sb->buf = buf;
41 sb->len = len;
42 sb->alloc = alloc;
43 strbuf_grow(sb, 0);
44 sb->buf[sb->len] = '\0';
45}
46
47void strbuf_grow(struct strbuf *sb, size_t extra)
48{
49 if (sb->len + extra + 1 <= sb->len)
50 die("you want to use way too much memory");
51 if (!sb->alloc)
52 sb->buf = NULL;
53 ALLOC_GROW(sb->buf, sb->len + extra + 1, sb->alloc);
54}
55
56void strbuf_trim(struct strbuf *sb)
57{
58 char *b = sb->buf;
59 while (sb->len > 0 && isspace((unsigned char)sb->buf[sb->len - 1]))
60 sb->len--;
61 while (sb->len > 0 && isspace(*b)) {
62 b++;
63 sb->len--;
64 }
65 memmove(sb->buf, b, sb->len);
66 sb->buf[sb->len] = '\0';
67}
68void strbuf_rtrim(struct strbuf *sb)
69{
70 while (sb->len > 0 && isspace((unsigned char)sb->buf[sb->len - 1]))
71 sb->len--;
72 sb->buf[sb->len] = '\0';
73}
74
75void strbuf_ltrim(struct strbuf *sb)
76{
77 char *b = sb->buf;
78 while (sb->len > 0 && isspace(*b)) {
79 b++;
80 sb->len--;
81 }
82 memmove(sb->buf, b, sb->len);
83 sb->buf[sb->len] = '\0';
84}
85
86void strbuf_tolower(struct strbuf *sb)
87{
88 int i;
89 for (i = 0; i < sb->len; i++)
90 sb->buf[i] = tolower(sb->buf[i]);
91}
92
93struct strbuf **strbuf_split(const struct strbuf *sb, int delim)
94{
95 int alloc = 2, pos = 0;
96 char *n, *p;
97 struct strbuf **ret;
98 struct strbuf *t;
99
100 ret = xcalloc(alloc, sizeof(struct strbuf *));
101 p = n = sb->buf;
102 while (n < sb->buf + sb->len) {
103 int len;
104 n = memchr(n, delim, sb->len - (n - sb->buf));
105 if (pos + 1 >= alloc) {
106 alloc = alloc * 2;
107 ret = xrealloc(ret, sizeof(struct strbuf *) * alloc);
108 }
109 if (!n)
110 n = sb->buf + sb->len - 1;
111 len = n - p + 1;
112 t = xmalloc(sizeof(struct strbuf));
113 strbuf_init(t, len);
114 strbuf_add(t, p, len);
115 ret[pos] = t;
116 ret[++pos] = NULL;
117 p = ++n;
118 }
119 return ret;
120}
121
122void strbuf_list_free(struct strbuf **sbs)
123{
124 struct strbuf **s = sbs;
125
126 while (*s) {
127 strbuf_release(*s);
128 free(*s++);
129 }
130 free(sbs);
131}
132
133int strbuf_cmp(const struct strbuf *a, const struct strbuf *b)
134{
135 int len = a->len < b->len ? a->len: b->len;
136 int cmp = memcmp(a->buf, b->buf, len);
137 if (cmp)
138 return cmp;
139 return a->len < b->len ? -1: a->len != b->len;
140}
141
142void strbuf_splice(struct strbuf *sb, size_t pos, size_t len,
143 const void *data, size_t dlen)
144{
145 if (pos + len < pos)
146 die("you want to use way too much memory");
147 if (pos > sb->len)
148 die("`pos' is too far after the end of the buffer");
149 if (pos + len > sb->len)
150 die("`pos + len' is too far after the end of the buffer");
151
152 if (dlen >= len)
153 strbuf_grow(sb, dlen - len);
154 memmove(sb->buf + pos + dlen,
155 sb->buf + pos + len,
156 sb->len - pos - len);
157 memcpy(sb->buf + pos, data, dlen);
158 strbuf_setlen(sb, sb->len + dlen - len);
159}
160
161void strbuf_insert(struct strbuf *sb, size_t pos, const void *data, size_t len)
162{
163 strbuf_splice(sb, pos, 0, data, len);
164}
165
166void strbuf_remove(struct strbuf *sb, size_t pos, size_t len)
167{
168 strbuf_splice(sb, pos, len, NULL, 0);
169}
170
171void strbuf_add(struct strbuf *sb, const void *data, size_t len)
172{
173 strbuf_grow(sb, len);
174 memcpy(sb->buf + sb->len, data, len);
175 strbuf_setlen(sb, sb->len + len);
176}
177
178void strbuf_adddup(struct strbuf *sb, size_t pos, size_t len)
179{
180 strbuf_grow(sb, len);
181 memcpy(sb->buf + sb->len, sb->buf + pos, len);
182 strbuf_setlen(sb, sb->len + len);
183}
184
185void strbuf_addf(struct strbuf *sb, const char *fmt, ...)
186{
187 int len;
188 va_list ap;
189
190 if (!strbuf_avail(sb))
191 strbuf_grow(sb, 64);
192 va_start(ap, fmt);
193 len = vsnprintf(sb->buf + sb->len, sb->alloc - sb->len, fmt, ap);
194 va_end(ap);
195 if (len < 0)
196 die("your vsnprintf is broken");
197 if (len > strbuf_avail(sb)) {
198 strbuf_grow(sb, len);
199 va_start(ap, fmt);
200 len = vsnprintf(sb->buf + sb->len, sb->alloc - sb->len, fmt, ap);
201 va_end(ap);
202 if (len > strbuf_avail(sb)) {
203 die("this should not happen, your snprintf is broken");
204 }
205 }
206 strbuf_setlen(sb, sb->len + len);
207}
208
209void strbuf_expand(struct strbuf *sb, const char *format, expand_fn_t fn,
210 void *context)
211{
212 for (;;) {
213 const char *percent;
214 size_t consumed;
215
216 percent = strchrnul(format, '%');
217 strbuf_add(sb, format, percent - format);
218 if (!*percent)
219 break;
220 format = percent + 1;
221
222 consumed = fn(sb, format, context);
223 if (consumed)
224 format += consumed;
225 else
226 strbuf_addch(sb, '%');
227 }
228}
229
230size_t strbuf_expand_dict_cb(struct strbuf *sb, const char *placeholder,
231 void *context)
232{
233 struct strbuf_expand_dict_entry *e = context;
234 size_t len;
235
236 for (; e->placeholder && (len = strlen(e->placeholder)); e++) {
237 if (!strncmp(placeholder, e->placeholder, len)) {
238 if (e->value)
239 strbuf_addstr(sb, e->value);
240 return len;
241 }
242 }
243 return 0;
244}
245
246size_t strbuf_fread(struct strbuf *sb, size_t size, FILE *f)
247{
248 size_t res;
249 size_t oldalloc = sb->alloc;
250
251 strbuf_grow(sb, size);
252 res = fread(sb->buf + sb->len, 1, size, f);
253 if (res > 0)
254 strbuf_setlen(sb, sb->len + res);
255 else if (res < 0 && oldalloc == 0)
256 strbuf_release(sb);
257 return res;
258}
259
260ssize_t strbuf_read(struct strbuf *sb, int fd, size_t hint)
261{
262 size_t oldlen = sb->len;
263 size_t oldalloc = sb->alloc;
264
265 strbuf_grow(sb, hint ? hint : 8192);
266 for (;;) {
267 ssize_t cnt;
268
269 cnt = _xread(fd, sb->buf + sb->len, sb->alloc - sb->len - 1);
270 if (cnt < 0) {
271 if (oldalloc == 0)
272 strbuf_release(sb);
273 else
274 strbuf_setlen(sb, oldlen);
275 return -1;
276 }
277 if (!cnt)
278 break;
279 sb->len += cnt;
280 strbuf_grow(sb, 8192);
281 }
282
283 sb->buf[sb->len] = '\0';
284 return sb->len - oldlen;
285}
286
287#define STRBUF_MAXLINK (2*PATH_MAX)
288
289int strbuf_readlink(struct strbuf *sb, const char *path, size_t hint)
290{
291 size_t oldalloc = sb->alloc;
292
293 if (hint < 32)
294 hint = 32;
295
296 while (hint < STRBUF_MAXLINK) {
297 int len;
298
299 strbuf_grow(sb, hint);
300 len = readlink(path, sb->buf, hint);
301 if (len < 0) {
302 if (errno != ERANGE)
303 break;
304 } else if (len < hint) {
305 strbuf_setlen(sb, len);
306 return 0;
307 }
308
309 /* .. the buffer was too small - try again */
310 hint *= 2;
311 }
312 if (oldalloc == 0)
313 strbuf_release(sb);
314 return -1;
315}
316
317int strbuf_getline(struct strbuf *sb, FILE *fp, int term)
318{
319 int ch;
320
321 strbuf_grow(sb, 0);
322 if (feof(fp))
323 return EOF;
324
325 strbuf_reset(sb);
326 while ((ch = fgetc(fp)) != EOF) {
327 if (ch == term)
328 break;
329 strbuf_grow(sb, 1);
330 sb->buf[sb->len++] = ch;
331 }
332 if (ch == EOF && sb->len == 0)
333 return EOF;
334
335 sb->buf[sb->len] = '\0';
336 return 0;
337}
338
339int strbuf_read_file(struct strbuf *sb, const char *path, size_t hint)
340{
341 int fd, len;
342
343 fd = open(path, O_RDONLY);
344 if (fd < 0)
345 return -1;
346 len = strbuf_read(sb, fd, hint);
347 close(fd);
348 if (len < 0)
349 return -1;
350
351 return len;
352}