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