annotate buf.c @ 127:e00bc8f7eabf

Fixed buf printf
author David Demelier <markand@malikania.fr>
date Wed, 07 Mar 2012 10:22:18 +0100
parents 911201e7574f
children 7e72d4008f6d
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 /*
127
e00bc8f7eabf Fixed buf printf
David Demelier <markand@malikania.fr>
parents: 126
diff changeset
114 * Concatenate the printf(3) like call to the string buffer, this function
125
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
127
e00bc8f7eabf Fixed buf printf
David Demelier <markand@malikania.fr>
parents: 126
diff changeset
127 do {
e00bc8f7eabf Fixed buf printf
David Demelier <markand@malikania.fr>
parents: 126
diff changeset
128 copied = vsnprintf(&buf->text[buf->length],
e00bc8f7eabf Fixed buf printf
David Demelier <markand@malikania.fr>
parents: 126
diff changeset
129 BUF_AVAIL(buf), fmt, ap);
125
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
130
127
e00bc8f7eabf Fixed buf printf
David Demelier <markand@malikania.fr>
parents: 126
diff changeset
131 buf->length = strlen(buf->text);
125
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
132
127
e00bc8f7eabf Fixed buf printf
David Demelier <markand@malikania.fr>
parents: 126
diff changeset
133 if (copied >= (signed int)BUF_AVAIL(buf) || copied == -1) {
125
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
134 if (BUF_FIXED(buf))
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
135 done = 1;
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 /*
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
138 * vsnprintf returns -1 on windows, we need to grow
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
139 * the buffer by block size.
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
140 */
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
141 if (grow(buf, buf->alsize + buf->bsize) < 0)
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
142 return -1;
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
143 } else {
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
144 done = 1;
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
145 }
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
146 } while (!done);
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
147
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
148 return 0;
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
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
151 int
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
152 buf_printf(struct buf *buf, const char *fmt, ...)
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
153 {
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
154 va_list ap;
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
155 int rv;
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
156
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
157 va_start(ap, fmt);
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
158 rv = buf_vprintf(buf, fmt, ap);
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
159 va_end(ap);
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
160
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
161 return rv;
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 /*
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
165 * Clear the string buffer.
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
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
168 void
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
169 buf_clear(struct buf *buf)
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
170 {
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
171 memset(buf->text, 0, buf->alsize);
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
172
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
173 buf->length = 0;
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
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
176 void
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
177 buf_free(struct buf *buf)
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
178 {
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
179 buf_clear(buf);
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
180
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
181 free(buf->text);
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
182 buf->text = NULL;
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 /*
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
186 * Valid options that can be set for a buffer :
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
187 * l -> optional buf block size of type int
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
188 * m -> malloc function that must matches void * (*malloc)(size_t)
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
189 * 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
190 * f -> buffer flags that are OR'ed
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
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
193 void
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
194 buf_set(struct buf *buf, const char *fmt, ...)
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
195 {
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
196 va_list ap;
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
197 const char *p;
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
198
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
199 va_start(ap, fmt);
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
200 for (p = fmt; *p != '\0'; ++p)
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
201 switch (*p) {
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
202 case 'l':
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
203 buf->bsize = va_arg(ap, int);
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
204 break;
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
205 case 'm':
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
206 buf->malloc = va_arg(ap, void *(*)(size_t));
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
207 break;
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
208 case 'r':
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
209 buf->realloc = va_arg(ap, void *(*)(void *, size_t));
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
210 break;
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
211 case 'f':
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
212 case 't':
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
213 buf->flags = va_arg(ap, int);
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
214 break;
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
215 default:
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
216 break;
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 /*
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
221 * 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
222 */
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
223
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
224 static void
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
225 copy(struct buf *buf, const void *ptr, size_t count)
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
226 {
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
227 memcpy(buf->text + buf->length, ptr, count);
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
228
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
229 buf->text[buf->length + count] = '\0';
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
230 buf->length += count;
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 /*
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
234 * 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
235 * size. This function may return -1 on allocation failure.
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
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
238 static int
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
239 grow(struct buf *buf, size_t needed)
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
240 {
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
241 while (BUF_AVAIL(buf) <= needed) {
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
242 buf->text = buf->realloc(buf->text, buf->alsize + buf->bsize);
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
243
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
244 if (buf->text == NULL)
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
245 return -1;
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
246
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
247 buf->alsize += buf->bsize;
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
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
250 return 0;
b9723c197038 Add brand new string buffer
David Demelier <markand@malikania.fr>
parents:
diff changeset
251 }