chiark / gitweb /
Add some more macros, particularly for creation and destruction.
[mLib] / dstr.h
CommitLineData
0875b58f 1/* -*-c-*-
2 *
c44b6bde 3 * $Id: dstr.h,v 1.6 1999/05/21 08:38:14 mdw Exp $
0875b58f 4 *
5 * Handle dynamically growing strings
6 *
7 * (c) 1998 Straylight/Edgeware
8 */
9
c846879c 10/*----- Licensing notice --------------------------------------------------*
0875b58f 11 *
12 * This file is part of the mLib utilities library.
13 *
14 * mLib is free software; you can redistribute it and/or modify
c846879c 15 * it under the terms of the GNU Library General Public License as
16 * published by the Free Software Foundation; either version 2 of the
17 * License, or (at your option) any later version.
18 *
0875b58f 19 * mLib is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
c846879c 22 * GNU Library General Public License for more details.
23 *
24 * You should have received a copy of the GNU Library General Public
0bd98442 25 * License along with mLib; if not, write to the Free
26 * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
27 * MA 02111-1307, USA.
0875b58f 28 */
29
30/*----- Revision history --------------------------------------------------*
31 *
32 * $Log: dstr.h,v $
c44b6bde 33 * Revision 1.6 1999/05/21 08:38:14 mdw
34 * Add some more macros, particularly for creation and destruction.
35 *
96c5fe33 36 * Revision 1.5 1999/05/13 22:47:57 mdw
37 * Misc documentation fixes. Change `-ise' to `-ize' throughout.
38 *
0bd98442 39 * Revision 1.4 1999/05/06 19:51:35 mdw
40 * Reformatted the LGPL notice a little bit.
41 *
c846879c 42 * Revision 1.3 1999/05/05 18:50:31 mdw
43 * Change licensing conditions to LGPL.
44 *
00c7638b 45 * Revision 1.2 1998/12/15 23:53:23 mdw
46 * New functions `dstr_putf' and `dstr_vputf' which do `printf'-style
47 * formatting in a safe way.
48 *
49 * Revision 1.1.1.1 1998/06/17 23:44:42 mdw
50 * Initial version of mLib
0875b58f 51 *
52 */
53
54#ifndef DSTR_H
55#define DSTR_H
56
57#ifdef __cplusplus
58 extern "C" {
59#endif
60
61/*----- Rationale ---------------------------------------------------------*
62 *
63 * This file declares what is hopefully a fairly useful collection of
64 * primitive string handling functions. The idea is that the strings
65 * allocate memory for themselves as required. The @dstr@ routines don't
66 * assume any sort of terminator character, so arbitrary binary data can
67 * be stored in a dynamic string. With luck, this should put a stop to
68 * any buffer overflow problems.
69 */
70
71/*----- Header files ------------------------------------------------------*/
72
00c7638b 73#include <stdarg.h>
0875b58f 74#include <stdio.h>
c44b6bde 75#include <stdlib.h>
0875b58f 76
77/*----- Data structures ---------------------------------------------------*/
78
79typedef struct dstr {
80 char *buf; /* Pointer to string buffer */
81 size_t sz; /* Size of the buffer */
82 size_t len; /* Length of the string */
83} dstr;
84
c44b6bde 85#define DSTR_INIT = { 0, 0, 0 }; /* How to initialize one */
86
0875b58f 87/*----- Functions provided ------------------------------------------------*/
88
89/* --- @dstr_create@ --- *
90 *
91 * Arguments: @dstr *d@ = pointer to a dynamic string block
92 *
93 * Returns: ---
94 *
96c5fe33 95 * Use: Initializes a dynamic string.
0875b58f 96 */
97
98extern void dstr_create(dstr */*d*/);
99
c44b6bde 100#define DCREATE(d) do { \
101 (d)->buf = 0; \
102 (d)->sz = 0; \
103 (d)->len = 0; \
104} while (0)
105
0875b58f 106/* --- @dstr_destroy@ --- *
107 *
108 * Arguments: @dstr *d@ = pointer to a dynamic string block
109 *
110 * Returns: ---
111 *
112 * Use: Reclaims the space used by a dynamic string.
113 */
114
115extern void dstr_destroy(dstr */*d*/);
116
c44b6bde 117#define DDESTROY(d) do { \
118 if ((d)->buf) free((d)->buf); \
119 DCREATE(d); \
120} while (0)
121
0875b58f 122/* --- @dstr_reset@ --- *
123 *
124 * Arguments: @dstr *d@ = pointer to a dynaimc string block
125 *
126 * Returns: ---
127 *
128 * Use: Resets a string so that new data gets put at the beginning.
129 */
130
131extern void dstr_reset(dstr */*d*/);
132
c44b6bde 133#define DRESET(d) do (d)->len = 0; while (0)
134
0875b58f 135/* --- @dstr_ensure@ --- *
136 *
137 * Arguments: @dstr *d@ = pointer to a dynamic string block
138 * @size_t sz@ = amount of free space to ensure
139 *
140 * Returns: ---
141 *
142 * Use: Ensures that at least @sz@ bytes are available in the
143 * given string.
144 */
145
146extern void dstr_ensure(dstr */*d*/, size_t /*sz*/);
147
148#define DENSURE(d, rq) do { \
149 if ((d)->len + (rq) > (d)->sz) dstr_ensure((d), (rq)); \
150} while (0)
151
152/* --- @dstr_putc@ --- *
153 *
154 * Arguments: @dstr *d@ = pointer to a dynamic string block
155 * @char ch@ = character to append
156 *
157 * Returns: ---
158 *
159 * Use: Appends a character to a string.
160 */
161
162extern void dstr_putc(dstr */*d*/, char /*ch*/);
163
164#define DPUTC(d, ch) do { \
165 DENSURE((d), 1); \
166 (d)->buf[(d)->len++] = (ch); \
167} while (0)
168
169/* --- @dstr_putz@ --- *
170 *
171 * Arguments: @dstr *d@ = pointer to a dynamic string block
172 *
173 * Returns: ---
174 *
175 * Use: Appends a null byte to a string. The null byte does not
176 * contribute to the string's length, and will be overwritten
177 * by subsequent `put' operations.
178 */
179
180extern void dstr_putz(dstr */*d*/);
181
182#define DPUTZ(d) do { \
183 DENSURE((d), 1); \
184 (d)->buf[(d)->len] = 0; \
185} while (0)
186
187/* --- @dstr_puts@ --- *
188 *
189 * Arguments: @dstr *d@ = pointer to a dynamic string block
190 * @const char *s@ = pointer to string to append
191 *
192 * Returns: ---
193 *
194 * Use: Appends a character string to a string. A trailing null
195 * byte is added, as for @dstr_putz@.
196 */
197
198extern void dstr_puts(dstr */*d*/, const char */*s*/);
199
200#define DPUTS(d, s) do { \
201 size_t sz = strlen(s); \
202 DENSURE((d), sz + 1); \
203 memcpy((d)->buf + (d)->len, (s), sz + 1); \
204 (d)->len += sz; \
205} while (0)
206
00c7638b 207/* --- @dstr_vputf@ --- *
208 *
209 * Arguments: @dstr *d@ = pointer to a dynamic string block
210 * @const char *p@ = pointer to @printf@-style format string
211 * @va_list ap@ = argument handle
212 *
96c5fe33 213 * Returns: The number of characters written to the string.
00c7638b 214 *
215 * Use: As for @dstr_putf@, but may be used as a back-end to user-
216 * supplied functions with @printf@-style interfaces.
217 */
218
219extern int dstr_vputf(dstr */*d*/, const char */*p*/, va_list /*ap*/);
220
221/* --- @dstr_putf@ --- *
222 *
223 * Arguments: @dstr *d@ = pointer to a dynamic string block
224 * @const char *p@ = pointer to @printf@-style format string
225 * @...@ = argument handle
226 *
96c5fe33 227 * Returns: The number of characters written to the string.
00c7638b 228 *
229 * Use: Writes a piece of text to a dynamic string, doing @printf@-
230 * style substitutions as it goes. Intended to be robust if
231 * faced with malicious arguments, but not if the format string
232 * itself is malicious.
233 */
234
235extern int dstr_putf(dstr */*d*/, const char */*p*/, ...);
236
0875b58f 237/* --- @dstr_putd@ --- *
238 *
239 * Arguments: @dstr *d@ = pointer to a dynamic string block
240 * @const dstr *s@ = pointer to a dynamic string to append
241 *
242 * Returns: ---
243 *
244 * Use: Appends a dynamic string to a string. A trailing null
245 * byte is added, as for @dstr_putz@.
246 */
247
248extern void dstr_putd(dstr */*d*/, const dstr */*s*/);
249
250#define DPUTD(d, s) do { \
251 DENSURE((d), (s)->len + 1); \
252 memcpy((d)->buf + (d)->len, (s)->buf, (s)->len); \
253 (d)->len += (s)->len; \
254 (d)->buf[(d)->len] = 0; \
255} while (0)
256
257/* --- @dstr_putm@ --- *
258 *
259 * Arguments: @dstr *d@ = pointer to a dynamic string block
260 * @const void *p@ = pointer to a block to append
261 * @size_t sz@ = size of the block
262 *
263 * Returns: Appends an arbitrary data block to a string. No trailing
264 * null is appended.
265 */
266
267extern void dstr_putm(dstr */*d*/, const void */*p*/, size_t /*sz*/);
268
269#define DPUTM(d, p, sz) do { \
270 DENSURE((d), (sz)); \
271 memcpy((d)->buf + (d)->len, (p), (sz)); \
272 (d)->len += (sz); \
273} while (0)
274
275/* --- @dstr_tidy@ --- *
276 *
277 * Arguments: @dstr *d@ = pointer to a dynamic string block
278 *
279 * Returns: ---
280 *
281 * Use: Reduces the amount of memory used by a string. A trailing
282 * null byte is added, as for @dstr_putz@.
283 */
284
285extern void dstr_tidy(dstr */*d*/);
286
287/* --- @dstr_putline@ --- *
288 *
289 * Arguments: @dstr *d@ = pointer to a dynamic string block
290 * @FILE *fp@ = a stream to read from
291 *
292 * Returns: The number of characters read into the buffer, or @EOF@ if
293 * end-of-file was reached before any characters were read.
294 *
295 * Use: Appends the next line from the given input stream to the
296 * string. A trailing newline is not added; a trailing null
297 * byte is appended, as for @dstr_putz@.
298 */
299
300extern int dstr_putline(dstr */*d*/, FILE */*fp*/);
301
302/* --- @dstr_write@ --- *
303 *
304 * Arguments: @dstr *d@ = pointer to a dynamic string block
305 * @FILE *fp@ = a stream to write on
306 *
307 * Returns: The number of bytes written (as for @fwrite@).
308 *
309 * Use: Writes a dynamic string to a file.
310 */
311
96c5fe33 312extern size_t dstr_write(const dstr */*d*/, FILE */*fp*/);
0875b58f 313
c44b6bde 314#define DWRITE(d, fp) fwrite((d)->buf, 1, (d)->len, (fp))
315
0875b58f 316/*----- That's all, folks -------------------------------------------------*/
317
318#ifdef __cplusplus
319 }
320#endif
321
322#endif