]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - usr.bin/make/buf.c
Stylification: missing spaces, extra space after function names, casts
[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(Buffer bp, int byte)
96 {
97     bp->left = 0;
98     BufExpand(bp, 1);
99
100     *bp->inPtr++ = byte;
101     bp->left--;
102
103     /*
104      * Null-terminate
105      */
106     *bp->inPtr = 0;
107 }
108
109 /*-
110  *-----------------------------------------------------------------------
111  * Buf_AddBytes --
112  *      Add a number of bytes to the buffer.
113  *
114  * Results:
115  *      None.
116  *
117  * Side Effects:
118  *      Guess what?
119  *
120  *-----------------------------------------------------------------------
121  */
122 void
123 Buf_AddBytes(Buffer bp, int numBytes, const Byte *bytesPtr)
124 {
125
126     BufExpand(bp, numBytes);
127
128     memcpy(bp->inPtr, bytesPtr, numBytes);
129     bp->inPtr += numBytes;
130     bp->left -= numBytes;
131
132     /*
133      * Null-terminate
134      */
135     *bp->inPtr = 0;
136 }
137
138 /*-
139  *-----------------------------------------------------------------------
140  * Buf_UngetByte --
141  *      Place the byte back at the beginning of the buffer.
142  *
143  * Results:
144  *      SUCCESS if the byte was added ok. FAILURE if not.
145  *
146  * Side Effects:
147  *      The byte is stuffed in the buffer and outPtr is decremented.
148  *
149  *-----------------------------------------------------------------------
150  */
151 void
152 Buf_UngetByte(Buffer bp, int byte)
153 {
154
155     if (bp->outPtr != bp->buffer) {
156         bp->outPtr--;
157         *bp->outPtr = byte;
158     } else if (bp->outPtr == bp->inPtr) {
159         *bp->inPtr = byte;
160         bp->inPtr++;
161         bp->left--;
162         *bp->inPtr = 0;
163     } else {
164         /*
165          * Yech. have to expand the buffer to stuff this thing in.
166          * We use a different expansion constant because people don't
167          * usually push back many bytes when they're doing it a byte at
168          * a time...
169          */
170         int       numBytes = bp->inPtr - bp->outPtr;
171         Byte      *newBuf;
172
173         newBuf = (Byte *)emalloc(bp->size + BUF_UNGET_INC);
174         memcpy((char *)(newBuf+BUF_UNGET_INC), (char *)bp->outPtr,
175             numBytes + 1);
176         bp->outPtr = newBuf + BUF_UNGET_INC;
177         bp->inPtr = bp->outPtr + numBytes;
178         free((char *)bp->buffer);
179         bp->buffer = newBuf;
180         bp->size += BUF_UNGET_INC;
181         bp->left = bp->size - (bp->inPtr - bp->buffer);
182         bp->outPtr -= 1;
183         *bp->outPtr = byte;
184     }
185 }
186
187 /*-
188  *-----------------------------------------------------------------------
189  * Buf_UngetBytes --
190  *      Push back a series of bytes at the beginning of the buffer.
191  *
192  * Results:
193  *      None.
194  *
195  * Side Effects:
196  *      outPtr is decremented and the bytes copied into the buffer.
197  *
198  *-----------------------------------------------------------------------
199  */
200 void
201 Buf_UngetBytes(Buffer bp, int numBytes, Byte *bytesPtr)
202 {
203
204     if (bp->outPtr - bp->buffer >= numBytes) {
205         bp->outPtr -= numBytes;
206         memcpy(bp->outPtr, bytesPtr, numBytes);
207     } else if (bp->outPtr == bp->inPtr) {
208         Buf_AddBytes(bp, numBytes, bytesPtr);
209     } else {
210         int       curNumBytes = bp->inPtr - bp->outPtr;
211         Byte      *newBuf;
212         int       newBytes = max(numBytes,BUF_UNGET_INC);
213
214         newBuf = (Byte *)emalloc (bp->size + newBytes);
215         memcpy((char *)(newBuf+newBytes), (char *)bp->outPtr, curNumBytes + 1);
216         bp->outPtr = newBuf + newBytes;
217         bp->inPtr = bp->outPtr + curNumBytes;
218         free((char *)bp->buffer);
219         bp->buffer = newBuf;
220         bp->size += newBytes;
221         bp->left = bp->size - (bp->inPtr - bp->buffer);
222         bp->outPtr -= numBytes;
223         memcpy((char *)bp->outPtr, (char *)bytesPtr, numBytes);
224     }
225 }
226
227 /*-
228  *-----------------------------------------------------------------------
229  * Buf_GetByte --
230  *      Return the next byte from the buffer. Actually returns an integer.
231  *
232  * Results:
233  *      Returns BUF_ERROR if there's no byte in the buffer, or the byte
234  *      itself if there is one.
235  *
236  * Side Effects:
237  *      outPtr is incremented and both outPtr and inPtr will be reset if
238  *      the buffer is emptied.
239  *
240  *-----------------------------------------------------------------------
241  */
242 int
243 Buf_GetByte(Buffer bp)
244 {
245     int     res;
246
247     if (bp->inPtr == bp->outPtr) {
248         return (BUF_ERROR);
249     } else {
250         res = (int)*bp->outPtr;
251         bp->outPtr += 1;
252         if (bp->outPtr == bp->inPtr) {
253             bp->outPtr = bp->inPtr = bp->buffer;
254             bp->left = bp->size;
255             *bp->inPtr = 0;
256         }
257         return (res);
258     }
259 }
260
261 /*-
262  *-----------------------------------------------------------------------
263  * Buf_GetBytes --
264  *      Extract a number of bytes from the buffer.
265  *
266  * Results:
267  *      The number of bytes gotten.
268  *
269  * Side Effects:
270  *      The passed array is overwritten.
271  *
272  *-----------------------------------------------------------------------
273  */
274 int
275 Buf_GetBytes(Buffer bp, int numBytes, Byte *bytesPtr)
276 {
277
278     if (bp->inPtr - bp->outPtr < numBytes) {
279         numBytes = bp->inPtr - bp->outPtr;
280     }
281     memcpy(bytesPtr, bp->outPtr, numBytes);
282     bp->outPtr += numBytes;
283
284     if (bp->outPtr == bp->inPtr) {
285         bp->outPtr = bp->inPtr = bp->buffer;
286         bp->left = bp->size;
287         *bp->inPtr = 0;
288     }
289     return (numBytes);
290 }
291
292 /*-
293  *-----------------------------------------------------------------------
294  * Buf_GetAll --
295  *      Get all the available data at once.
296  *
297  * Results:
298  *      A pointer to the data and the number of bytes available.
299  *
300  * Side Effects:
301  *      None.
302  *
303  *-----------------------------------------------------------------------
304  */
305 Byte *
306 Buf_GetAll(Buffer bp, int *numBytesPtr)
307 {
308
309     if (numBytesPtr != (int *)NULL) {
310         *numBytesPtr = bp->inPtr - bp->outPtr;
311     }
312
313     return (bp->outPtr);
314 }
315
316 /*-
317  *-----------------------------------------------------------------------
318  * Buf_Discard --
319  *      Throw away bytes in a buffer.
320  *
321  * Results:
322  *      None.
323  *
324  * Side Effects:
325  *      The bytes are discarded.
326  *
327  *-----------------------------------------------------------------------
328  */
329 void
330 Buf_Discard(Buffer bp, int numBytes)
331 {
332
333     if (bp->inPtr - bp->outPtr <= numBytes) {
334         bp->inPtr = bp->outPtr = bp->buffer;
335         bp->left = bp->size;
336         *bp->inPtr = 0;
337     } else {
338         bp->outPtr += numBytes;
339     }
340 }
341
342 /*-
343  *-----------------------------------------------------------------------
344  * Buf_Size --
345  *      Returns the number of bytes in the given buffer. Doesn't include
346  *      the null-terminating byte.
347  *
348  * Results:
349  *      The number of bytes.
350  *
351  * Side Effects:
352  *      None.
353  *
354  *-----------------------------------------------------------------------
355  */
356 int
357 Buf_Size(Buffer buf)
358 {
359     return (buf->inPtr - buf->outPtr);
360 }
361
362 /*-
363  *-----------------------------------------------------------------------
364  * Buf_Init --
365  *      Initialize a buffer. If no initial size is given, a reasonable
366  *      default is used.
367  *
368  * Results:
369  *      A buffer to be given to other functions in this library.
370  *
371  * Side Effects:
372  *      The buffer is created, the space allocated and pointers
373  *      initialized.
374  *
375  *-----------------------------------------------------------------------
376  */
377 Buffer
378 Buf_Init(int size)
379 {
380     Buffer bp;          /* New Buffer */
381
382     bp = (Buffer)emalloc(sizeof(*bp));
383
384     if (size <= 0) {
385         size = BUF_DEF_SIZE;
386     }
387     bp->left = bp->size = size;
388     bp->buffer = (Byte *)emalloc(size);
389     bp->inPtr = bp->outPtr = bp->buffer;
390     *bp->inPtr = 0;
391
392     return (bp);
393 }
394
395 /*-
396  *-----------------------------------------------------------------------
397  * Buf_Destroy --
398  *      Destroy a buffer, and optionally free its data, too.
399  *
400  * Results:
401  *      None.
402  *
403  * Side Effects:
404  *      The buffer is freed.
405  *
406  *-----------------------------------------------------------------------
407  */
408 void
409 Buf_Destroy(Buffer buf, Boolean freeData)
410 {
411
412     if (freeData) {
413         free((char *)buf->buffer);
414     }
415     free((char *)buf);
416 }
417
418 /*-
419  *-----------------------------------------------------------------------
420  * Buf_ReplaceLastByte --
421  *     Replace the last byte in a buffer.
422  *
423  * Results:
424  *     None.
425  *
426  * Side Effects:
427  *     If the buffer was empty intially, then a new byte will be added.
428  *     Otherwise, the last byte is overwritten.
429  *
430  *-----------------------------------------------------------------------
431  */
432 void
433 Buf_ReplaceLastByte(Buffer buf, int byte)
434 {
435     if (buf->inPtr == buf->outPtr)
436         Buf_AddByte(buf, byte);
437     else
438         *(buf->inPtr - 1) = byte;
439 }