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