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