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