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