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