]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - usr.bin/make/buf.c
This commit was generated by cvs2svn to compensate for changes in r89397,
[FreeBSD/FreeBSD.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  */
40
41 #ifndef lint
42 #include <sys/cdefs.h>
43 __RCSID("$FreeBSD$");
44 #endif /* not lint */
45
46 /*-
47  * buf.c --
48  *      Functions for automatically-expanded buffers.
49  */
50
51 #include    "sprite.h"
52 #include    "make.h"
53 #include    "buf.h"
54
55 #ifndef max
56 #define max(a,b)  ((a) > (b) ? (a) : (b))
57 #endif
58
59 /*
60  * BufExpand --
61  *      Expand the given buffer to hold the given number of additional
62  *      bytes.
63  *      Makes sure there's room for an extra NULL byte at the end of the
64  *      buffer in case it holds a string.
65  */
66 #define BufExpand(bp,nb) \
67         if (bp->left < (nb)+1) {\
68             int newSize = (bp)->size + max((nb)+1,BUF_ADD_INC); \
69             Byte  *newBuf = (Byte *) erealloc((bp)->buffer, newSize); \
70             \
71             (bp)->inPtr = newBuf + ((bp)->inPtr - (bp)->buffer); \
72             (bp)->outPtr = newBuf + ((bp)->outPtr - (bp)->buffer);\
73             (bp)->buffer = newBuf;\
74             (bp)->size = newSize;\
75             (bp)->left = newSize - ((bp)->inPtr - (bp)->buffer);\
76         }
77
78 #define BUF_DEF_SIZE    256     /* Default buffer size */
79 #define BUF_ADD_INC     256     /* Expansion increment when Adding */
80 #define BUF_UNGET_INC   16      /* Expansion increment when Ungetting */
81
82 /*-
83  *-----------------------------------------------------------------------
84  * Buf_OvAddByte --
85  *      Add a single byte to the buffer.  left is zero or negative.
86  *
87  * Results:
88  *      None.
89  *
90  * Side Effects:
91  *      The buffer may be expanded.
92  *
93  *-----------------------------------------------------------------------
94  */
95 void
96 Buf_OvAddByte (bp, byte)
97     register Buffer bp;
98     int    byte;
99 {
100     int nbytes = 1;
101     bp->left = 0;
102     BufExpand (bp, nbytes);
103
104     *bp->inPtr++ = byte;
105     bp->left--;
106
107     /*
108      * Null-terminate
109      */
110     *bp->inPtr = 0;
111 }
112 \f
113 /*-
114  *-----------------------------------------------------------------------
115  * Buf_AddBytes --
116  *      Add a number of bytes to the buffer.
117  *
118  * Results:
119  *      None.
120  *
121  * Side Effects:
122  *      Guess what?
123  *
124  *-----------------------------------------------------------------------
125  */
126 void
127 Buf_AddBytes (bp, numBytes, bytesPtr)
128     register Buffer bp;
129     int     numBytes;
130     const Byte *bytesPtr;
131 {
132
133     BufExpand (bp, numBytes);
134
135     memcpy (bp->inPtr, bytesPtr, numBytes);
136     bp->inPtr += numBytes;
137     bp->left -= numBytes;
138
139     /*
140      * Null-terminate
141      */
142     *bp->inPtr = 0;
143 }
144 \f
145 /*-
146  *-----------------------------------------------------------------------
147  * Buf_UngetByte --
148  *      Place the byte back at the beginning of the buffer.
149  *
150  * Results:
151  *      SUCCESS if the byte was added ok. FAILURE if not.
152  *
153  * Side Effects:
154  *      The byte is stuffed in the buffer and outPtr is decremented.
155  *
156  *-----------------------------------------------------------------------
157  */
158 void
159 Buf_UngetByte (bp, byte)
160     register Buffer bp;
161     int    byte;
162 {
163
164     if (bp->outPtr != bp->buffer) {
165         bp->outPtr--;
166         *bp->outPtr = byte;
167     } else if (bp->outPtr == bp->inPtr) {
168         *bp->inPtr = byte;
169         bp->inPtr++;
170         bp->left--;
171         *bp->inPtr = 0;
172     } else {
173         /*
174          * Yech. have to expand the buffer to stuff this thing in.
175          * We use a different expansion constant because people don't
176          * usually push back many bytes when they're doing it a byte at
177          * a time...
178          */
179         int       numBytes = bp->inPtr - bp->outPtr;
180         Byte      *newBuf;
181
182         newBuf = (Byte *)emalloc(bp->size + BUF_UNGET_INC);
183         memcpy ((char *)(newBuf+BUF_UNGET_INC), (char *)bp->outPtr, numBytes+1);
184         bp->outPtr = newBuf + BUF_UNGET_INC;
185         bp->inPtr = bp->outPtr + numBytes;
186         free ((char *)bp->buffer);
187         bp->buffer = newBuf;
188         bp->size += BUF_UNGET_INC;
189         bp->left = bp->size - (bp->inPtr - bp->buffer);
190         bp->outPtr -= 1;
191         *bp->outPtr = byte;
192     }
193 }
194 \f
195 /*-
196  *-----------------------------------------------------------------------
197  * Buf_UngetBytes --
198  *      Push back a series of bytes at the beginning of the buffer.
199  *
200  * Results:
201  *      None.
202  *
203  * Side Effects:
204  *      outPtr is decremented and the bytes copied into the buffer.
205  *
206  *-----------------------------------------------------------------------
207  */
208 void
209 Buf_UngetBytes (bp, numBytes, bytesPtr)
210     register Buffer bp;
211     int     numBytes;
212     Byte    *bytesPtr;
213 {
214
215     if (bp->outPtr - bp->buffer >= numBytes) {
216         bp->outPtr -= numBytes;
217         memcpy (bp->outPtr, bytesPtr, numBytes);
218     } else if (bp->outPtr == bp->inPtr) {
219         Buf_AddBytes (bp, numBytes, bytesPtr);
220     } else {
221         int       curNumBytes = bp->inPtr - bp->outPtr;
222         Byte      *newBuf;
223         int       newBytes = max(numBytes,BUF_UNGET_INC);
224
225         newBuf = (Byte *)emalloc (bp->size + newBytes);
226         memcpy((char *)(newBuf+newBytes), (char *)bp->outPtr, curNumBytes+1);
227         bp->outPtr = newBuf + newBytes;
228         bp->inPtr = bp->outPtr + curNumBytes;
229         free ((char *)bp->buffer);
230         bp->buffer = newBuf;
231         bp->size += newBytes;
232         bp->left = bp->size - (bp->inPtr - bp->buffer);
233         bp->outPtr -= numBytes;
234         memcpy ((char *)bp->outPtr, (char *)bytesPtr, numBytes);
235     }
236 }
237 \f
238 /*-
239  *-----------------------------------------------------------------------
240  * Buf_GetByte --
241  *      Return the next byte from the buffer. Actually returns an integer.
242  *
243  * Results:
244  *      Returns BUF_ERROR if there's no byte in the buffer, or the byte
245  *      itself if there is one.
246  *
247  * Side Effects:
248  *      outPtr is incremented and both outPtr and inPtr will be reset if
249  *      the buffer is emptied.
250  *
251  *-----------------------------------------------------------------------
252  */
253 int
254 Buf_GetByte (bp)
255     register Buffer bp;
256 {
257     int     res;
258
259     if (bp->inPtr == bp->outPtr) {
260         return (BUF_ERROR);
261     } else {
262         res = (int) *bp->outPtr;
263         bp->outPtr += 1;
264         if (bp->outPtr == bp->inPtr) {
265             bp->outPtr = bp->inPtr = bp->buffer;
266             bp->left = bp->size;
267             *bp->inPtr = 0;
268         }
269         return (res);
270     }
271 }
272 \f
273 /*-
274  *-----------------------------------------------------------------------
275  * Buf_GetBytes --
276  *      Extract a number of bytes from the buffer.
277  *
278  * Results:
279  *      The number of bytes gotten.
280  *
281  * Side Effects:
282  *      The passed array is overwritten.
283  *
284  *-----------------------------------------------------------------------
285  */
286 int
287 Buf_GetBytes (bp, numBytes, bytesPtr)
288     register Buffer bp;
289     int     numBytes;
290     Byte    *bytesPtr;
291 {
292
293     if (bp->inPtr - bp->outPtr < numBytes) {
294         numBytes = bp->inPtr - bp->outPtr;
295     }
296     memcpy (bytesPtr, bp->outPtr, numBytes);
297     bp->outPtr += numBytes;
298
299     if (bp->outPtr == bp->inPtr) {
300         bp->outPtr = bp->inPtr = bp->buffer;
301         bp->left = bp->size;
302         *bp->inPtr = 0;
303     }
304     return (numBytes);
305 }
306 \f
307 /*-
308  *-----------------------------------------------------------------------
309  * Buf_GetAll --
310  *      Get all the available data at once.
311  *
312  * Results:
313  *      A pointer to the data and the number of bytes available.
314  *
315  * Side Effects:
316  *      None.
317  *
318  *-----------------------------------------------------------------------
319  */
320 Byte *
321 Buf_GetAll (bp, numBytesPtr)
322     register Buffer bp;
323     int     *numBytesPtr;
324 {
325
326     if (numBytesPtr != (int *)NULL) {
327         *numBytesPtr = bp->inPtr - bp->outPtr;
328     }
329
330     return (bp->outPtr);
331 }
332 \f
333 /*-
334  *-----------------------------------------------------------------------
335  * Buf_Discard --
336  *      Throw away bytes in a buffer.
337  *
338  * Results:
339  *      None.
340  *
341  * Side Effects:
342  *      The bytes are discarded.
343  *
344  *-----------------------------------------------------------------------
345  */
346 void
347 Buf_Discard (bp, numBytes)
348     register Buffer bp;
349     int     numBytes;
350 {
351
352     if (bp->inPtr - bp->outPtr <= numBytes) {
353         bp->inPtr = bp->outPtr = bp->buffer;
354         bp->left = bp->size;
355         *bp->inPtr = 0;
356     } else {
357         bp->outPtr += numBytes;
358     }
359 }
360 \f
361 /*-
362  *-----------------------------------------------------------------------
363  * Buf_Size --
364  *      Returns the number of bytes in the given buffer. Doesn't include
365  *      the null-terminating byte.
366  *
367  * Results:
368  *      The number of bytes.
369  *
370  * Side Effects:
371  *      None.
372  *
373  *-----------------------------------------------------------------------
374  */
375 int
376 Buf_Size (buf)
377     Buffer  buf;
378 {
379     return (buf->inPtr - buf->outPtr);
380 }
381 \f
382 /*-
383  *-----------------------------------------------------------------------
384  * Buf_Init --
385  *      Initialize a buffer. If no initial size is given, a reasonable
386  *      default is used.
387  *
388  * Results:
389  *      A buffer to be given to other functions in this library.
390  *
391  * Side Effects:
392  *      The buffer is created, the space allocated and pointers
393  *      initialized.
394  *
395  *-----------------------------------------------------------------------
396  */
397 Buffer
398 Buf_Init (size)
399     int     size;       /* Initial size for the buffer */
400 {
401     Buffer bp;          /* New Buffer */
402
403     bp = (Buffer)emalloc(sizeof(*bp));
404
405     if (size <= 0) {
406         size = BUF_DEF_SIZE;
407     }
408     bp->left = bp->size = size;
409     bp->buffer = (Byte *)emalloc(size);
410     bp->inPtr = bp->outPtr = bp->buffer;
411     *bp->inPtr = 0;
412
413     return (bp);
414 }
415 \f
416 /*-
417  *-----------------------------------------------------------------------
418  * Buf_Destroy --
419  *      Nuke a buffer and all its resources.
420  *
421  * Results:
422  *      None.
423  *
424  * Side Effects:
425  *      The buffer is freed.
426  *
427  *-----------------------------------------------------------------------
428  */
429 void
430 Buf_Destroy (buf, freeData)
431     Buffer  buf;        /* Buffer to destroy */
432     Boolean freeData;   /* TRUE if the data should be destroyed as well */
433 {
434
435     if (freeData) {
436         free ((char *)buf->buffer);
437     }
438     free ((char *)buf);
439 }
440 \f
441 /*-
442  *-----------------------------------------------------------------------
443  * Buf_ReplaceLastByte --
444  *     Replace the last byte in a buffer.
445  *
446  * Results:
447  *     None.
448  *
449  * Side Effects:
450  *     If the buffer was empty intially, then a new byte will be added.
451  *     Otherwise, the last byte is overwritten.
452  *
453  *-----------------------------------------------------------------------
454  */
455 void
456 Buf_ReplaceLastByte (buf, byte)
457     Buffer buf; /* buffer to augment */
458     int byte;   /* byte to be written */
459 {
460     if (buf->inPtr == buf->outPtr)
461         Buf_AddByte(buf, byte);
462     else
463         *(buf->inPtr - 1) = byte;
464 }