xref: /netbsd-src/usr.bin/make/buf.c (revision d48f14661dda8638fee055ba15d35bdfb29b9fa8)
1 /*	$NetBSD: buf.c,v 1.19 2005/08/08 16:42:54 christos Exp $	*/
2 
3 /*
4  * Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
5  * All rights reserved.
6  *
7  * This code is derived from software contributed to Berkeley by
8  * Adam de Boor.
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions
12  * are met:
13  * 1. Redistributions of source code must retain the above copyright
14  *    notice, this list of conditions and the following disclaimer.
15  * 2. Redistributions in binary form must reproduce the above copyright
16  *    notice, this list of conditions and the following disclaimer in the
17  *    documentation and/or other materials provided with the distribution.
18  * 3. Neither the name of the University nor the names of its contributors
19  *    may be used to endorse or promote products derived from this software
20  *    without specific prior written permission.
21  *
22  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32  * SUCH DAMAGE.
33  */
34 
35 /*
36  * Copyright (c) 1988, 1989 by Adam de Boor
37  * Copyright (c) 1989 by Berkeley Softworks
38  * All rights reserved.
39  *
40  * This code is derived from software contributed to Berkeley by
41  * Adam de Boor.
42  *
43  * Redistribution and use in source and binary forms, with or without
44  * modification, are permitted provided that the following conditions
45  * are met:
46  * 1. Redistributions of source code must retain the above copyright
47  *    notice, this list of conditions and the following disclaimer.
48  * 2. Redistributions in binary form must reproduce the above copyright
49  *    notice, this list of conditions and the following disclaimer in the
50  *    documentation and/or other materials provided with the distribution.
51  * 3. All advertising materials mentioning features or use of this software
52  *    must display the following acknowledgement:
53  *	This product includes software developed by the University of
54  *	California, Berkeley and its contributors.
55  * 4. Neither the name of the University nor the names of its contributors
56  *    may be used to endorse or promote products derived from this software
57  *    without specific prior written permission.
58  *
59  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
60  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
61  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
62  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
63  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
64  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
65  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
66  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
67  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
68  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
69  * SUCH DAMAGE.
70  */
71 
72 #ifndef MAKE_NATIVE
73 static char rcsid[] = "$NetBSD: buf.c,v 1.19 2005/08/08 16:42:54 christos Exp $";
74 #else
75 #include <sys/cdefs.h>
76 #ifndef lint
77 #if 0
78 static char sccsid[] = "@(#)buf.c	8.1 (Berkeley) 6/6/93";
79 #else
80 __RCSID("$NetBSD: buf.c,v 1.19 2005/08/08 16:42:54 christos Exp $");
81 #endif
82 #endif /* not lint */
83 #endif
84 
85 /*-
86  * buf.c --
87  *	Functions for automatically-expanded buffers.
88  */
89 
90 #include    "sprite.h"
91 #include    "make.h"
92 #include    "buf.h"
93 
94 #ifndef max
95 #define max(a,b)  ((a) > (b) ? (a) : (b))
96 #endif
97 
98 /*
99  * BufExpand --
100  * 	Expand the given buffer to hold the given number of additional
101  *	bytes.
102  *	Makes sure there's room for an extra NULL byte at the end of the
103  *	buffer in case it holds a string.
104  */
105 #define BufExpand(bp,nb) \
106  	while (bp->left < (nb)+1) {\
107 	    int newSize = (bp)->size * 2; \
108 	    Byte  *newBuf = (Byte *)erealloc((bp)->buffer, newSize); \
109 	    \
110 	    (bp)->inPtr = newBuf + ((bp)->inPtr - (bp)->buffer); \
111 	    (bp)->outPtr = newBuf + ((bp)->outPtr - (bp)->buffer);\
112 	    (bp)->buffer = newBuf;\
113 	    (bp)->size = newSize;\
114 	    (bp)->left = newSize - ((bp)->inPtr - (bp)->buffer);\
115 	}
116 
117 #define BUF_DEF_SIZE	256 	/* Default buffer size */
118 
119 /*-
120  *-----------------------------------------------------------------------
121  * Buf_OvAddByte --
122  *	Add a single byte to the buffer.  left is zero or negative.
123  *
124  * Results:
125  *	None.
126  *
127  * Side Effects:
128  *	The buffer may be expanded.
129  *
130  *-----------------------------------------------------------------------
131  */
132 void
133 Buf_OvAddByte(Buffer bp, int byte)
134 {
135     int nbytes = 1;
136     bp->left = 0;
137     BufExpand(bp, nbytes);
138 
139     *bp->inPtr++ = byte;
140     bp->left--;
141 
142     /*
143      * Null-terminate
144      */
145     *bp->inPtr = 0;
146 }
147 
148 /*-
149  *-----------------------------------------------------------------------
150  * Buf_AddBytes --
151  *	Add a number of bytes to the buffer.
152  *
153  * Results:
154  *	None.
155  *
156  * Side Effects:
157  *	Guess what?
158  *
159  *-----------------------------------------------------------------------
160  */
161 void
162 Buf_AddBytes(Buffer bp, int numBytes, const Byte *bytesPtr)
163 {
164 
165     BufExpand(bp, numBytes);
166 
167     memcpy(bp->inPtr, bytesPtr, numBytes);
168     bp->inPtr += numBytes;
169     bp->left -= numBytes;
170 
171     /*
172      * Null-terminate
173      */
174     *bp->inPtr = 0;
175 }
176 
177 /*-
178  *-----------------------------------------------------------------------
179  * Buf_GetAll --
180  *	Get all the available data at once.
181  *
182  * Results:
183  *	A pointer to the data and the number of bytes available.
184  *
185  * Side Effects:
186  *	None.
187  *
188  *-----------------------------------------------------------------------
189  */
190 Byte *
191 Buf_GetAll(Buffer bp, int *numBytesPtr)
192 {
193 
194     if (numBytesPtr != NULL) {
195 	*numBytesPtr = bp->inPtr - bp->outPtr;
196     }
197 
198     return (bp->outPtr);
199 }
200 
201 /*-
202  *-----------------------------------------------------------------------
203  * Buf_Discard --
204  *	Throw away bytes in a buffer.
205  *
206  * Results:
207  *	None.
208  *
209  * Side Effects:
210  *	The bytes are discarded.
211  *
212  *-----------------------------------------------------------------------
213  */
214 void
215 Buf_Discard(Buffer bp, int numBytes)
216 {
217 
218     if (bp->inPtr - bp->outPtr <= numBytes) {
219 	bp->inPtr = bp->outPtr = bp->buffer;
220 	bp->left = bp->size;
221 	*bp->inPtr = 0;
222     } else {
223 	bp->outPtr += numBytes;
224     }
225 }
226 
227 /*-
228  *-----------------------------------------------------------------------
229  * Buf_Size --
230  *	Returns the number of bytes in the given buffer. Doesn't include
231  *	the null-terminating byte.
232  *
233  * Results:
234  *	The number of bytes.
235  *
236  * Side Effects:
237  *	None.
238  *
239  *-----------------------------------------------------------------------
240  */
241 int
242 Buf_Size(Buffer buf)
243 {
244     return (buf->inPtr - buf->outPtr);
245 }
246 
247 /*-
248  *-----------------------------------------------------------------------
249  * Buf_Init --
250  *	Initialize a buffer. If no initial size is given, a reasonable
251  *	default is used.
252  *
253  * Input:
254  *	size		Initial size for the buffer
255  *
256  * Results:
257  *	A buffer to be given to other functions in this library.
258  *
259  * Side Effects:
260  *	The buffer is created, the space allocated and pointers
261  *	initialized.
262  *
263  *-----------------------------------------------------------------------
264  */
265 Buffer
266 Buf_Init(int size)
267 {
268     Buffer bp;	  	/* New Buffer */
269 
270     bp = emalloc(sizeof(*bp));
271 
272     if (size <= 0) {
273 	size = BUF_DEF_SIZE;
274     }
275     bp->left = bp->size = size;
276     bp->buffer = emalloc(size);
277     bp->inPtr = bp->outPtr = bp->buffer;
278     *bp->inPtr = 0;
279 
280     return (bp);
281 }
282 
283 /*-
284  *-----------------------------------------------------------------------
285  * Buf_Destroy --
286  *	Nuke a buffer and all its resources.
287  *
288  * Input:
289  *	buf		Buffer to destroy
290  *	freeData	TRUE if the data should be destroyed
291  *
292  * Results:
293  *	None.
294  *
295  * Side Effects:
296  *	The buffer is freed.
297  *
298  *-----------------------------------------------------------------------
299  */
300 void
301 Buf_Destroy(Buffer buf, Boolean freeData)
302 {
303 
304     if (freeData) {
305 	free(buf->buffer);
306     }
307     free(buf);
308 }
309 
310 /*-
311  *-----------------------------------------------------------------------
312  * Buf_ReplaceLastByte --
313  *     Replace the last byte in a buffer.
314  *
315  * Input:
316  *	buf		buffer to augment
317  *	byte		byte to be written
318  *
319  * Results:
320  *     None.
321  *
322  * Side Effects:
323  *     If the buffer was empty intially, then a new byte will be added.
324  *     Otherwise, the last byte is overwritten.
325  *
326  *-----------------------------------------------------------------------
327  */
328 void
329 Buf_ReplaceLastByte(Buffer buf, int byte)
330 {
331     if (buf->inPtr == buf->outPtr)
332         Buf_AddByte(buf, byte);
333     else
334         *(buf->inPtr - 1) = byte;
335 }
336