]>
Commit | Line | Data |
---|---|---|
812666c8 | 1 | #include "cache.h" |
85023577 | 2 | #include "strbuf.h" |
d1df5743 JH |
3 | |
4 | void strbuf_init(struct strbuf *sb) { | |
b449f4cf | 5 | memset(sb, 0, sizeof(*sb)); |
d1df5743 JH |
6 | } |
7 | ||
b449f4cf | 8 | void strbuf_release(struct strbuf *sb) { |
d1df5743 | 9 | free(sb->buf); |
b449f4cf PH |
10 | memset(sb, 0, sizeof(*sb)); |
11 | } | |
12 | ||
13 | void strbuf_reset(struct strbuf *sb) { | |
14 | if (sb->len) | |
15 | strbuf_setlen(sb, 0); | |
16 | sb->eof = 0; | |
17 | } | |
18 | ||
19 | char *strbuf_detach(struct strbuf *sb) { | |
20 | char *res = sb->buf; | |
d1df5743 | 21 | strbuf_init(sb); |
b449f4cf PH |
22 | return res; |
23 | } | |
24 | ||
25 | void strbuf_grow(struct strbuf *sb, size_t extra) { | |
26 | if (sb->len + extra + 1 <= sb->len) | |
27 | die("you want to use way too much memory"); | |
28 | ALLOC_GROW(sb->buf, sb->len + extra + 1, sb->alloc); | |
29 | } | |
30 | ||
31 | void strbuf_add(struct strbuf *sb, const void *data, size_t len) { | |
32 | strbuf_grow(sb, len); | |
33 | memcpy(sb->buf + sb->len, data, len); | |
34 | strbuf_setlen(sb, sb->len + len); | |
35 | } | |
36 | ||
37 | void strbuf_addf(struct strbuf *sb, const char *fmt, ...) { | |
38 | int len; | |
39 | va_list ap; | |
40 | ||
41 | va_start(ap, fmt); | |
42 | len = vsnprintf(sb->buf + sb->len, sb->alloc - sb->len, fmt, ap); | |
43 | va_end(ap); | |
44 | if (len < 0) { | |
45 | len = 0; | |
46 | } | |
47 | if (len >= strbuf_avail(sb)) { | |
48 | strbuf_grow(sb, len); | |
49 | va_start(ap, fmt); | |
50 | len = vsnprintf(sb->buf + sb->len, sb->alloc - sb->len, fmt, ap); | |
51 | va_end(ap); | |
52 | if (len >= strbuf_avail(sb)) { | |
53 | die("this should not happen, your snprintf is broken"); | |
54 | } | |
55 | } | |
56 | strbuf_setlen(sb, sb->len + len); | |
d1df5743 JH |
57 | } |
58 | ||
b449f4cf PH |
59 | size_t strbuf_fread(struct strbuf *sb, size_t size, FILE *f) { |
60 | size_t res; | |
61 | ||
62 | strbuf_grow(sb, size); | |
63 | res = fread(sb->buf + sb->len, 1, size, f); | |
64 | if (res > 0) { | |
65 | strbuf_setlen(sb, sb->len + res); | |
d1df5743 | 66 | } |
b449f4cf | 67 | return res; |
d1df5743 JH |
68 | } |
69 | ||
b449f4cf PH |
70 | ssize_t strbuf_read(struct strbuf *sb, int fd) |
71 | { | |
72 | size_t oldlen = sb->len; | |
73 | ||
74 | for (;;) { | |
75 | ssize_t cnt; | |
76 | ||
77 | strbuf_grow(sb, 8192); | |
78 | cnt = xread(fd, sb->buf + sb->len, sb->alloc - sb->len - 1); | |
79 | if (cnt < 0) { | |
80 | strbuf_setlen(sb, oldlen); | |
81 | return -1; | |
82 | } | |
83 | if (!cnt) | |
84 | break; | |
85 | sb->len += cnt; | |
86 | } | |
87 | ||
88 | sb->buf[sb->len] = '\0'; | |
89 | return sb->len - oldlen; | |
d1df5743 JH |
90 | } |
91 | ||
92 | void read_line(struct strbuf *sb, FILE *fp, int term) { | |
93 | int ch; | |
d1df5743 | 94 | if (feof(fp)) { |
b449f4cf | 95 | strbuf_release(sb); |
d1df5743 JH |
96 | sb->eof = 1; |
97 | return; | |
98 | } | |
b449f4cf PH |
99 | |
100 | strbuf_reset(sb); | |
d1df5743 JH |
101 | while ((ch = fgetc(fp)) != EOF) { |
102 | if (ch == term) | |
103 | break; | |
b449f4cf PH |
104 | strbuf_grow(sb, 1); |
105 | sb->buf[sb->len++] = ch; | |
d1df5743 | 106 | } |
b449f4cf PH |
107 | if (ch == EOF && sb->len == 0) { |
108 | strbuf_release(sb); | |
9dc527ad | 109 | sb->eof = 1; |
b449f4cf PH |
110 | } |
111 | ||
112 | strbuf_grow(sb, 1); | |
113 | sb->buf[sb->len] = '\0'; | |
d1df5743 | 114 | } |