annotate buf.c @ 125:b9723c197038

Add brand new string buffer
author David Demelier <markand@malikania.fr>
date Wed, 07 Mar 2012 09:51:01 +0100
parents
children 911201e7574f
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
125
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
1 /*
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
2 * buf.c -- easy way to manipulate strings
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
3 *
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
4 * Copyright (c) 2011, 2012, David Demelier <markand@malikania.fr>
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
5 *
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
6 * Permission to use, copy, modify, and/or distribute this software for any
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
7 * purpose with or without fee is hereby granted, provided that the above
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
8 * copyright notice and this permission notice appear in all copies.
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
9 *
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
17 */
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
18
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
19 #include <stdio.h>
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
20 #include <stdlib.h>
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
21 #include <string.h>
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
22
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
23 #include "buf.h"
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
24
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
25 #define BUF_AVAIL(buf) ((buf)->alsize - (buf)->length - 1)
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
26 #define BUF_SAFE(buf) (!((buf)->flags & BUF_UNSAFE))
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
27 #define BUF_FIXED(buf) ((buf)->flags & BUF_FIXED)
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
28 #define BUF_AUTO(buf) (buf->flags == 0)
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
29
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
30 static void copy(struct buf *, const void *, size_t);
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
31 static int grow(struct buf *, size_t);
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
32
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
33 int
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
34 buf_init(struct buf *buf)
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
35 {
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
36 /* Set defaults if needed */
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
37 buf->bsize = (buf->bsize <= 0) ? BUF_DEFAULT_BSIZE : buf->bsize;
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
38 buf->alsize = buf->bsize + 1;
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
39 buf->malloc = (buf->malloc == NULL) ? &malloc : buf->malloc;
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
40 buf->realloc = (buf->realloc == NULL) ? &realloc : buf->realloc;
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
41
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
42 if ((buf->text = buf->malloc(buf->alsize)) == NULL)
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
43 return -1;
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
44
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
45 memset(buf->text, 0, buf->alsize);
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
46
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
47 return 0;
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
48 }
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
49
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
50 /*
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
51 * This function appends not more than max characters from str.
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
52 */
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
53
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
54 int
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
55 buf_ncat(struct buf *buf, const char *str, size_t max)
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
56 {
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
57 size_t tocopy = max;
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
58
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
59 for (tocopy = 0; str[tocopy] != '\0' && tocopy < max; ++tocopy)
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
60 continue;
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
61
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
62 if (BUF_AVAIL(buf) < tocopy) {
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
63 /* Can't add more */
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
64 if (BUF_SAFE(buf) && BUF_FIXED(buf))
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
65 return -1;
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
66
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
67 if (BUF_AUTO(buf)) {
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
68 if (grow(buf, tocopy) < 0)
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
69 return -1;
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
70 } else {
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
71 /* String is unsafe, truncate to the available size */
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
72 tocopy = BUF_AVAIL(buf);
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
73 }
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
74 }
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
75
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
76 copy(buf, str, tocopy);
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
77
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
78 return 0;
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
79 }
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
80
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
81 /*
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
82 * Append the string str to the end of the string buffer.
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
83 */
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
84
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
85 int
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
86 buf_cat(struct buf *buf, const char *str)
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
87 {
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
88 return buf_ncat(buf, str, strlen(str));
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
89 }
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
90
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
91 /*
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
92 * Copy at most max character from str to string buffer.
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
93 */
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
94
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
95 int
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
96 buf_ncopy(struct buf *buf, const char *str, size_t max)
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
97 {
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
98 buf_clear(buf);
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
99
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
100 return buf_ncat(buf, str, max);
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
101 }
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
102
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
103 /*
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
104 * Copy the string str to the string buffer.
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
105 */
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
106
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
107 int
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
108 buf_copy(struct buf *buf, const char *str)
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
109 {
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
110 return buf_ncopy(buf, str, strlen(str));
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
111 }
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
112
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
113 /*
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
114 * Copy the printf(3) like call to the string buffer, this function
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
115 * returns -1 on fixed safe buffer, otherwise 0 is returned if there
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
116 * is no allocation failure.
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
117 */
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
118
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
119 int
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
120 buf_vprintf(struct buf *buf, const char *fmt, va_list ap)
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
121 {
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
122 int copied, done = 0;
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
123
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
124 if (BUF_FIXED(buf) && BUF_SAFE(buf))
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
125 return -1;
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
126
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
127 buf_clear(buf);
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
128
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
129 do {
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
130 copied = vsnprintf(buf->text, buf->alsize, fmt, ap);
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
131
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
132 if (copied > BUF_AVAIL(buf)) {
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
133 if (BUF_FIXED(buf))
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
134 done = 1;
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
135
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
136 /*
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
137 * vsnprintf returns -1 on windows, we need to grow
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
138 * the buffer by block size.
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
139 */
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
140 if (grow(buf, buf->alsize + buf->bsize) < 0)
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
141 return -1;
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
142 } else {
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
143 done = 1;
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
144 }
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
145 } while (!done);
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
146
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
147 return 0;
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
148 }
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
149
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
150 int
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
151 buf_printf(struct buf *buf, const char *fmt, ...)
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
152 {
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
153 va_list ap;
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
154 int rv;
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
155
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
156 va_start(ap, fmt);
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
157 rv = buf_vprintf(buf, fmt, ap);
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
158 va_end(ap);
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
159
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
160 return rv;
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
161 }
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
162
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
163 /*
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
164 * Clear the string buffer.
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
165 */
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
166
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
167 void
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
168 buf_clear(struct buf *buf)
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
169 {
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
170 memset(buf->text, 0, buf->alsize);
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
171
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
172 buf->length = 0;
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
173 }
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
174
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
175 void
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
176 buf_free(struct buf *buf)
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
177 {
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
178 buf_clear(buf);
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
179
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
180 free(buf->text);
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
181 buf->text = NULL;
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
182 }
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
183
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
184 /*
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
185 * Valid options that can be set for a buffer :
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
186 * l -> optional buf block size of type int
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
187 * m -> malloc function that must matches void * (*malloc)(size_t)
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
188 * r -> realloc function that must matches void * (*realloc)(void *, size_t)
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
189 * f -> buffer flags that are OR'ed
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
190 */
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
191
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
192 void
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
193 buf_set(struct buf *buf, const char *fmt, ...)
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
194 {
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
195 va_list ap;
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
196 const char *p;
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
197
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
198 va_start(ap, fmt);
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
199 for (p = fmt; *p != '\0'; ++p)
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
200 switch (*p) {
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
201 case 'l':
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
202 buf->bsize = va_arg(ap, int);
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
203 break;
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
204 case 'm':
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
205 buf->malloc = va_arg(ap, void *(*)(size_t));
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
206 break;
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
207 case 'r':
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
208 buf->realloc = va_arg(ap, void *(*)(void *, size_t));
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
209 break;
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
210 case 'f':
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
211 case 't':
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
212 buf->flags = va_arg(ap, int);
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
213 break;
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
214 default:
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
215 break;
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
216 }
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
217 }
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
218
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
219 /*
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
220 * Append to the end of buffer the void ptr of count size.
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
221 */
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
222
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
223 static void
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
224 copy(struct buf *buf, const void *ptr, size_t count)
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
225 {
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
226 memcpy(buf->text + buf->length, ptr, count);
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
227
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
228 buf->text[buf->length + count] = '\0';
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
229 buf->length += count;
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
230 }
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
231
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
232 /*
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
233 * Grow the text buffer until the available size fit the needed
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
234 * size. This function may return -1 on allocation failure.
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
235 */
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
236
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
237 static int
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
238 grow(struct buf *buf, size_t needed)
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
239 {
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
240 while (BUF_AVAIL(buf) <= needed) {
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
241 buf->text = buf->realloc(buf->text, buf->alsize + buf->bsize);
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
242
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
243 if (buf->text == NULL)
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
244 return -1;
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
245
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
246 buf->alsize += buf->bsize;
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
247 }
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
248
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
249 return 0;
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
250 }