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