]>
Commit | Line | Data |
---|---|---|
812666c8 | 1 | #include "cache.h" |
d1df5743 | 2 | |
917c9a71 PH |
3 | void strbuf_init(struct strbuf *sb, size_t hint) |
4 | { | |
b449f4cf | 5 | memset(sb, 0, sizeof(*sb)); |
f1696ee3 PH |
6 | if (hint) |
7 | strbuf_grow(sb, hint); | |
d1df5743 JH |
8 | } |
9 | ||
917c9a71 PH |
10 | void strbuf_release(struct strbuf *sb) |
11 | { | |
d1df5743 | 12 | free(sb->buf); |
b449f4cf PH |
13 | memset(sb, 0, sizeof(*sb)); |
14 | } | |
15 | ||
917c9a71 PH |
16 | void strbuf_reset(struct strbuf *sb) |
17 | { | |
b449f4cf PH |
18 | if (sb->len) |
19 | strbuf_setlen(sb, 0); | |
20 | sb->eof = 0; | |
21 | } | |
22 | ||
917c9a71 PH |
23 | char *strbuf_detach(struct strbuf *sb) |
24 | { | |
b449f4cf | 25 | char *res = sb->buf; |
f1696ee3 | 26 | strbuf_init(sb, 0); |
b449f4cf PH |
27 | return res; |
28 | } | |
29 | ||
917c9a71 PH |
30 | void strbuf_attach(struct strbuf *sb, void *buf, size_t len, size_t alloc) |
31 | { | |
32 | strbuf_release(sb); | |
33 | sb->buf = buf; | |
34 | sb->len = len; | |
35 | sb->alloc = alloc; | |
36 | strbuf_grow(sb, 0); | |
37 | sb->buf[sb->len] = '\0'; | |
38 | } | |
39 | ||
40 | void strbuf_grow(struct strbuf *sb, size_t extra) | |
41 | { | |
b449f4cf PH |
42 | if (sb->len + extra + 1 <= sb->len) |
43 | die("you want to use way too much memory"); | |
44 | ALLOC_GROW(sb->buf, sb->len + extra + 1, sb->alloc); | |
45 | } | |
46 | ||
f1696ee3 PH |
47 | void strbuf_rtrim(struct strbuf *sb) |
48 | { | |
49 | while (sb->len > 0 && isspace((unsigned char)sb->buf[sb->len - 1])) | |
50 | sb->len--; | |
51 | sb->buf[sb->len] = '\0'; | |
52 | } | |
53 | ||
917c9a71 PH |
54 | void strbuf_insert(struct strbuf *sb, size_t pos, const void *data, size_t len) |
55 | { | |
f1696ee3 | 56 | strbuf_grow(sb, len); |
917c9a71 PH |
57 | if (pos > sb->len) |
58 | die("`pos' is too far after the end of the buffer"); | |
59 | memmove(sb->buf + pos + len, sb->buf + pos, sb->len - pos); | |
f1696ee3 PH |
60 | memcpy(sb->buf + pos, data, len); |
61 | strbuf_setlen(sb, sb->len + len); | |
62 | } | |
63 | ||
917c9a71 PH |
64 | void strbuf_splice(struct strbuf *sb, size_t pos, size_t len, |
65 | const void *data, size_t dlen) | |
66 | { | |
67 | if (pos + len < pos) | |
68 | die("you want to use way too much memory"); | |
69 | if (pos > sb->len) | |
70 | die("`pos' is too far after the end of the buffer"); | |
71 | if (pos + len > sb->len) | |
72 | die("`pos + len' is too far after the end of the buffer"); | |
73 | ||
74 | if (dlen >= len) | |
75 | strbuf_grow(sb, dlen - len); | |
76 | memmove(sb->buf + pos + dlen, | |
77 | sb->buf + pos + len, | |
78 | sb->len - pos - len); | |
79 | memcpy(sb->buf + pos, data, dlen); | |
80 | strbuf_setlen(sb, sb->len + dlen - len); | |
81 | } | |
82 | ||
83 | void strbuf_add(struct strbuf *sb, const void *data, size_t len) | |
84 | { | |
b449f4cf PH |
85 | strbuf_grow(sb, len); |
86 | memcpy(sb->buf + sb->len, data, len); | |
87 | strbuf_setlen(sb, sb->len + len); | |
88 | } | |
89 | ||
917c9a71 PH |
90 | void strbuf_addf(struct strbuf *sb, const char *fmt, ...) |
91 | { | |
b449f4cf PH |
92 | int len; |
93 | va_list ap; | |
94 | ||
95 | va_start(ap, fmt); | |
96 | len = vsnprintf(sb->buf + sb->len, sb->alloc - sb->len, fmt, ap); | |
97 | va_end(ap); | |
98 | if (len < 0) { | |
99 | len = 0; | |
100 | } | |
f1696ee3 | 101 | if (len > strbuf_avail(sb)) { |
b449f4cf PH |
102 | strbuf_grow(sb, len); |
103 | va_start(ap, fmt); | |
104 | len = vsnprintf(sb->buf + sb->len, sb->alloc - sb->len, fmt, ap); | |
105 | va_end(ap); | |
f1696ee3 | 106 | if (len > strbuf_avail(sb)) { |
b449f4cf PH |
107 | die("this should not happen, your snprintf is broken"); |
108 | } | |
109 | } | |
110 | strbuf_setlen(sb, sb->len + len); | |
d1df5743 JH |
111 | } |
112 | ||
917c9a71 PH |
113 | size_t strbuf_fread(struct strbuf *sb, size_t size, FILE *f) |
114 | { | |
b449f4cf PH |
115 | size_t res; |
116 | ||
117 | strbuf_grow(sb, size); | |
118 | res = fread(sb->buf + sb->len, 1, size, f); | |
119 | if (res > 0) { | |
120 | strbuf_setlen(sb, sb->len + res); | |
d1df5743 | 121 | } |
b449f4cf | 122 | return res; |
d1df5743 JH |
123 | } |
124 | ||
f1696ee3 | 125 | ssize_t strbuf_read(struct strbuf *sb, int fd, size_t hint) |
b449f4cf PH |
126 | { |
127 | size_t oldlen = sb->len; | |
128 | ||
f1696ee3 | 129 | strbuf_grow(sb, hint ? hint : 8192); |
b449f4cf PH |
130 | for (;;) { |
131 | ssize_t cnt; | |
132 | ||
b449f4cf PH |
133 | cnt = xread(fd, sb->buf + sb->len, sb->alloc - sb->len - 1); |
134 | if (cnt < 0) { | |
135 | strbuf_setlen(sb, oldlen); | |
136 | return -1; | |
137 | } | |
138 | if (!cnt) | |
139 | break; | |
140 | sb->len += cnt; | |
f1696ee3 | 141 | strbuf_grow(sb, 8192); |
b449f4cf PH |
142 | } |
143 | ||
144 | sb->buf[sb->len] = '\0'; | |
145 | return sb->len - oldlen; | |
d1df5743 JH |
146 | } |
147 | ||
917c9a71 PH |
148 | void read_line(struct strbuf *sb, FILE *fp, int term) |
149 | { | |
d1df5743 | 150 | int ch; |
d1df5743 | 151 | if (feof(fp)) { |
b449f4cf | 152 | strbuf_release(sb); |
d1df5743 JH |
153 | sb->eof = 1; |
154 | return; | |
155 | } | |
b449f4cf PH |
156 | |
157 | strbuf_reset(sb); | |
d1df5743 JH |
158 | while ((ch = fgetc(fp)) != EOF) { |
159 | if (ch == term) | |
160 | break; | |
b449f4cf PH |
161 | strbuf_grow(sb, 1); |
162 | sb->buf[sb->len++] = ch; | |
d1df5743 | 163 | } |
b449f4cf PH |
164 | if (ch == EOF && sb->len == 0) { |
165 | strbuf_release(sb); | |
9dc527ad | 166 | sb->eof = 1; |
b449f4cf PH |
167 | } |
168 | ||
169 | strbuf_grow(sb, 1); | |
170 | sb->buf[sb->len] = '\0'; | |
d1df5743 | 171 | } |