Merge from vendor branch GCC:
[dragonfly.git] / usr.bin / make / buf.c
1 /*
2  * Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
3  * Copyright (c) 1988, 1989 by Adam de Boor
4  * Copyright (c) 1989 by Berkeley Softworks
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. All advertising materials mentioning features or use of this software
19  *    must display the following acknowledgement:
20  *      This product includes software developed by the University of
21  *      California, Berkeley and its contributors.
22  * 4. Neither the name of the University nor the names of its contributors
23  *    may be used to endorse or promote products derived from this software
24  *    without specific prior written permission.
25  *
26  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
27  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
29  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
30  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
31  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
32  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
33  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
34  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
35  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
36  * SUCH DAMAGE.
37  *
38  * @(#)buf.c    8.1 (Berkeley) 6/6/93
39  * $FreeBSD: src/usr.bin/make/buf.c,v 1.11 1999/09/11 13:08:01 hoek Exp $
40  * $DragonFly: src/usr.bin/make/buf.c,v 1.2 2003/06/17 04:29:28 dillon Exp $
41  */
42
43 /*-
44  * buf.c --
45  *      Functions for automatically-expanded buffers.
46  */
47
48 #include    "sprite.h"
49 #include    "make.h"
50 #include    "buf.h"
51
52 #ifndef max
53 #define max(a,b)  ((a) > (b) ? (a) : (b))
54 #endif
55
56 /*
57  * BufExpand --
58  *      Expand the given buffer to hold the given number of additional
59  *      bytes.
60  *      Makes sure there's room for an extra NULL byte at the end of the
61  *      buffer in case it holds a string.
62  */
63 #define BufExpand(bp,nb) \
64         if (bp->left < (nb)+1) {\
65             int newSize = (bp)->size + max((nb)+1,BUF_ADD_INC); \
66             Byte  *newBuf = (Byte *) erealloc((bp)->buffer, newSize); \
67             \
68             (bp)->inPtr = newBuf + ((bp)->inPtr - (bp)->buffer); \
69             (bp)->outPtr = newBuf + ((bp)->outPtr - (bp)->buffer);\
70             (bp)->buffer = newBuf;\
71             (bp)->size = newSize;\
72             (bp)->left = newSize - ((bp)->inPtr - (bp)->buffer);\
73         }
74
75 #define BUF_DEF_SIZE    256     /* Default buffer size */
76 #define BUF_ADD_INC     256     /* Expansion increment when Adding */
77 #define BUF_UNGET_INC   16      /* Expansion increment when Ungetting */
78
79 /*-
80  *-----------------------------------------------------------------------
81  * Buf_OvAddByte --
82  *      Add a single byte to the buffer.  left is zero or negative.
83  *
84  * Results:
85  *      None.
86  *
87  * Side Effects:
88  *      The buffer may be expanded.
89  *
90  *-----------------------------------------------------------------------
91  */
92 void
93 Buf_OvAddByte (bp, byte)
94     register Buffer bp;
95     int    byte;
96 {
97     int nbytes = 1;
98     bp->left = 0;
99     BufExpand (bp, nbytes);
100
101     *bp->inPtr++ = byte;
102     bp->left--;
103
104     /*
105      * Null-terminate
106      */
107     *bp->inPtr = 0;
108 }
109 \f
110 /*-
111  *-----------------------------------------------------------------------
112  * Buf_AddBytes --
113  *      Add a number of bytes to the buffer.
114  *
115  * Results:
116  *      None.
117  *
118  * Side Effects:
119  *      Guess what?
120  *
121  *-----------------------------------------------------------------------
122  */
123 void
124 Buf_AddBytes (bp, numBytes, bytesPtr)
125     register Buffer bp;
126     int     numBytes;
127     const Byte *bytesPtr;
128 {
129
130     BufExpand (bp, numBytes);
131
132     memcpy (bp->inPtr, bytesPtr, numBytes);
133     bp->inPtr += numBytes;
134     bp->left -= numBytes;
135
136     /*
137      * Null-terminate
138      */
139     *bp->inPtr = 0;
140 }
141 \f
142 /*-
143  *-----------------------------------------------------------------------
144  * Buf_UngetByte --
145  *      Place the byte back at the beginning of the buffer.
146  *
147  * Results:
148  *      SUCCESS if the byte was added ok. FAILURE if not.
149  *
150  * Side Effects:
151  *      The byte is stuffed in the buffer and outPtr is decremented.
152  *
153  *-----------------------------------------------------------------------
154  */
155 void
156 Buf_UngetByte (bp, byte)
157     register Buffer bp;
158     int    byte;
159 {
160
161     if (bp->outPtr != bp->buffer) {
162         bp->outPtr--;
163         *bp->outPtr = byte;
164     } else if (bp->outPtr == bp->inPtr) {
165         *bp->inPtr = byte;
166         bp->inPtr++;
167         bp->left--;
168         *bp->inPtr = 0;
169     } else {
170         /*
171          * Yech. have to expand the buffer to stuff this thing in.
172          * We use a different expansion constant because people don't
173          * usually push back many bytes when they're doing it a byte at
174          * a time...
175          */
176         int       numBytes = bp->inPtr - bp->outPtr;
177         Byte      *newBuf;
178
179         newBuf = (Byte *)emalloc(bp->size + BUF_UNGET_INC);
180         memcpy ((char *)(newBuf+BUF_UNGET_INC), (char *)bp->outPtr, numBytes+1);
181         bp->outPtr = newBuf + BUF_UNGET_INC;
182         bp->inPtr = bp->outPtr + numBytes;
183         free ((char *)bp->buffer);
184         bp->buffer = newBuf;
185         bp->size += BUF_UNGET_INC;
186         bp->left = bp->size - (bp->inPtr - bp->buffer);
187         bp->outPtr -= 1;
188         *bp->outPtr = byte;
189     }
190 }
191 \f
192 /*-
193  *-----------------------------------------------------------------------
194  * Buf_UngetBytes --
195  *      Push back a series of bytes at the beginning of the buffer.
196  *
197  * Results:
198  *      None.
199  *
200  * Side Effects:
201  *      outPtr is decremented and the bytes copied into the buffer.
202  *
203  *-----------------------------------------------------------------------
204  */
205 void
206 Buf_UngetBytes (bp, numBytes, bytesPtr)
207     register Buffer bp;
208     int     numBytes;
209     Byte    *bytesPtr;
210 {
211
212     if (bp->outPtr - bp->buffer >= numBytes) {
213         bp->outPtr -= numBytes;
214         memcpy (bp->outPtr, bytesPtr, numBytes);
215     } else if (bp->outPtr == bp->inPtr) {
216         Buf_AddBytes (bp, numBytes, bytesPtr);
217     } else {
218         int       curNumBytes = bp->inPtr - bp->outPtr;
219         Byte      *newBuf;
220         int       newBytes = max(numBytes,BUF_UNGET_INC);
221
222         newBuf = (Byte *)emalloc (bp->size + newBytes);
223         memcpy((char *)(newBuf+newBytes), (char *)bp->outPtr, curNumBytes+1);
224         bp->outPtr = newBuf + newBytes;
225         bp->inPtr = bp->outPtr + curNumBytes;
226         free ((char *)bp->buffer);
227         bp->buffer = newBuf;
228         bp->size += newBytes;
229         bp->left = bp->size - (bp->inPtr - bp->buffer);
230         bp->outPtr -= numBytes;
231         memcpy ((char *)bp->outPtr, (char *)bytesPtr, numBytes);
232     }
233 }
234 \f
235 /*-
236  *-----------------------------------------------------------------------
237  * Buf_GetByte --
238  *      Return the next byte from the buffer. Actually returns an integer.
239  *
240  * Results:
241  *      Returns BUF_ERROR if there's no byte in the buffer, or the byte
242  *      itself if there is one.
243  *
244  * Side Effects:
245  *      outPtr is incremented and both outPtr and inPtr will be reset if
246  *      the buffer is emptied.
247  *
248  *-----------------------------------------------------------------------
249  */
250 int
251 Buf_GetByte (bp)
252     register Buffer bp;
253 {
254     int     res;
255
256     if (bp->inPtr == bp->outPtr) {
257         return (BUF_ERROR);
258     } else {
259         res = (int) *bp->outPtr;
260         bp->outPtr += 1;
261         if (bp->outPtr == bp->inPtr) {
262             bp->outPtr = bp->inPtr = bp->buffer;
263             bp->left = bp->size;
264             *bp->inPtr = 0;
265         }
266         return (res);
267     }
268 }
269 \f
270 /*-
271  *-----------------------------------------------------------------------
272  * Buf_GetBytes --
273  *      Extract a number of bytes from the buffer.
274  *
275  * Results:
276  *      The number of bytes gotten.
277  *
278  * Side Effects:
279  *      The passed array is overwritten.
280  *
281  *-----------------------------------------------------------------------
282  */
283 int
284 Buf_GetBytes (bp, numBytes, bytesPtr)
285     register Buffer bp;
286     int     numBytes;
287     Byte    *bytesPtr;
288 {
289
290     if (bp->inPtr - bp->outPtr < numBytes) {
291         numBytes = bp->inPtr - bp->outPtr;
292     }
293     memcpy (bytesPtr, bp->outPtr, numBytes);
294     bp->outPtr += numBytes;
295
296     if (bp->outPtr == bp->inPtr) {
297         bp->outPtr = bp->inPtr = bp->buffer;
298         bp->left = bp->size;
299         *bp->inPtr = 0;
300     }
301     return (numBytes);
302 }
303 \f
304 /*-
305  *-----------------------------------------------------------------------
306  * Buf_GetAll --
307  *      Get all the available data at once.
308  *
309  * Results:
310  *      A pointer to the data and the number of bytes available.
311  *
312  * Side Effects:
313  *      None.
314  *
315  *-----------------------------------------------------------------------
316  */
317 Byte *
318 Buf_GetAll (bp, numBytesPtr)
319     register Buffer bp;
320     int     *numBytesPtr;
321 {
322
323     if (numBytesPtr != (int *)NULL) {
324         *numBytesPtr = bp->inPtr - bp->outPtr;
325     }
326
327     return (bp->outPtr);
328 }
329 \f
330 /*-
331  *-----------------------------------------------------------------------
332  * Buf_Discard --
333  *      Throw away bytes in a buffer.
334  *
335  * Results:
336  *      None.
337  *
338  * Side Effects:
339  *      The bytes are discarded.
340  *
341  *-----------------------------------------------------------------------
342  */
343 void
344 Buf_Discard (bp, numBytes)
345     register Buffer bp;
346     int     numBytes;
347 {
348
349     if (bp->inPtr - bp->outPtr <= numBytes) {
350         bp->inPtr = bp->outPtr = bp->buffer;
351         bp->left = bp->size;
352         *bp->inPtr = 0;
353     } else {
354         bp->outPtr += numBytes;
355     }
356 }
357 \f
358 /*-
359  *-----------------------------------------------------------------------
360  * Buf_Size --
361  *      Returns the number of bytes in the given buffer. Doesn't include
362  *      the null-terminating byte.
363  *
364  * Results:
365  *      The number of bytes.
366  *
367  * Side Effects:
368  *      None.
369  *
370  *-----------------------------------------------------------------------
371  */
372 int
373 Buf_Size (buf)
374     Buffer  buf;
375 {
376     return (buf->inPtr - buf->outPtr);
377 }
378 \f
379 /*-
380  *-----------------------------------------------------------------------
381  * Buf_Init --
382  *      Initialize a buffer. If no initial size is given, a reasonable
383  *      default is used.
384  *
385  * Results:
386  *      A buffer to be given to other functions in this library.
387  *
388  * Side Effects:
389  *      The buffer is created, the space allocated and pointers
390  *      initialized.
391  *
392  *-----------------------------------------------------------------------
393  */
394 Buffer
395 Buf_Init (size)
396     int     size;       /* Initial size for the buffer */
397 {
398     Buffer bp;          /* New Buffer */
399
400     bp = (Buffer)emalloc(sizeof(*bp));
401
402     if (size <= 0) {
403         size = BUF_DEF_SIZE;
404     }
405     bp->left = bp->size = size;
406     bp->buffer = (Byte *)emalloc(size);
407     bp->inPtr = bp->outPtr = bp->buffer;
408     *bp->inPtr = 0;
409
410     return (bp);
411 }
412 \f
413 /*-
414  *-----------------------------------------------------------------------
415  * Buf_Destroy --
416  *      Nuke a buffer and all its resources.
417  *
418  * Results:
419  *      None.
420  *
421  * Side Effects:
422  *      The buffer is freed.
423  *
424  *-----------------------------------------------------------------------
425  */
426 void
427 Buf_Destroy (buf, freeData)
428     Buffer  buf;        /* Buffer to destroy */
429     Boolean freeData;   /* TRUE if the data should be destroyed as well */
430 {
431
432     if (freeData) {
433         free ((char *)buf->buffer);
434     }
435     free ((char *)buf);
436 }
437 \f
438 /*-
439  *-----------------------------------------------------------------------
440  * Buf_ReplaceLastByte --
441  *     Replace the last byte in a buffer.
442  *
443  * Results:
444  *     None.
445  *
446  * Side Effects:
447  *     If the buffer was empty intially, then a new byte will be added.
448  *     Otherwise, the last byte is overwritten.
449  *
450  *-----------------------------------------------------------------------
451  */
452 void
453 Buf_ReplaceLastByte (buf, byte)
454     Buffer buf; /* buffer to augment */
455     int byte;   /* byte to be written */
456 {
457     if (buf->inPtr == buf->outPtr)
458         Buf_AddByte(buf, byte);
459     else
460         *(buf->inPtr - 1) = byte;
461 }