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