Hiding pointer in typedefs is evil. 'Buffer *' -> 'Buffer'
[dragonfly.git] / usr.bin / make / buf.c
CommitLineData
984263bc 1/*
9a309bcc
MD
2 * Copyright (c) 1988, 1989, 1990, 1993
3 * The Regents of the University of California. All rights reserved.
984263bc
MD
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.
1de703da
MD
38 *
39 * @(#)buf.c 8.1 (Berkeley) 6/6/93
40 * $FreeBSD: src/usr.bin/make/buf.c,v 1.11 1999/09/11 13:08:01 hoek Exp $
6a3d9147 41 * $DragonFly: src/usr.bin/make/buf.c,v 1.13 2005/01/06 13:18:58 okumoto Exp $
984263bc
MD
42 */
43
984263bc
MD
44/*-
45 * buf.c --
46 * Functions for automatically-expanded buffers.
47 */
48
9863ce62
MO
49#include <string.h>
50#include <stdlib.h>
51
1e609a21 52#include "buf.h"
9863ce62
MO
53#include "sprite.h"
54#include "util.h"
984263bc
MD
55
56#ifndef max
913800f5 57#define max(a,b) ((a) > (b) ? (a) : (b))
984263bc
MD
58#endif
59
60/*
61 * BufExpand --
62 * Expand the given buffer to hold the given number of additional
63 * bytes.
64 * Makes sure there's room for an extra NULL byte at the end of the
65 * buffer in case it holds a string.
66 */
1e609a21 67#define BufExpand(bp, nb) do { \
4f762dd1 68 if ((bp)->left < (nb) + 1) { \
1e609a21 69 int newSize = (bp)->size + max((nb) + 1, BUF_ADD_INC); \
960bbbf7 70 Byte *newBuf = erealloc((bp)->buffer, newSize); \
1e609a21
MO
71 \
72 (bp)->inPtr = newBuf + ((bp)->inPtr - (bp)->buffer); \
73 (bp)->outPtr = newBuf + ((bp)->outPtr - (bp)->buffer); \
74 (bp)->buffer = newBuf; \
75 (bp)->size = newSize; \
76 (bp)->left = newSize - ((bp)->inPtr - (bp)->buffer); \
77 } \
78 } while (0)
984263bc 79
913800f5
MD
80#define BUF_DEF_SIZE 256 /* Default buffer size */
81#define BUF_ADD_INC 256 /* Expansion increment when Adding */
82#define BUF_UNGET_INC 16 /* Expansion increment when Ungetting */
984263bc
MD
83
84/*-
85 *-----------------------------------------------------------------------
86 * Buf_OvAddByte --
87 * Add a single byte to the buffer. left is zero or negative.
88 *
89 * Results:
90 * None.
91 *
92 * Side Effects:
93 * The buffer may be expanded.
94 *
95 *-----------------------------------------------------------------------
96 */
97void
6a3d9147 98Buf_OvAddByte(Buffer *bp, Byte byte)
984263bc 99{
9a4c88c2 100
1e609a21
MO
101 bp->left = 0;
102 BufExpand(bp, 1);
984263bc 103
1e609a21
MO
104 *bp->inPtr++ = byte;
105 bp->left--;
984263bc 106
1e609a21
MO
107 /*
108 * Null-terminate
109 */
110 *bp->inPtr = 0;
984263bc 111}
fbfaa208 112
984263bc
MD
113/*-
114 *-----------------------------------------------------------------------
115 * Buf_AddBytes --
116 * Add a number of bytes to the buffer.
117 *
118 * Results:
119 * None.
120 *
121 * Side Effects:
122 * Guess what?
123 *
124 *-----------------------------------------------------------------------
125 */
126void
6a3d9147 127Buf_AddBytes(Buffer *bp, size_t numBytes, const Byte *bytesPtr)
984263bc
MD
128{
129
1e609a21 130 BufExpand(bp, numBytes);
984263bc 131
1e609a21
MO
132 memcpy(bp->inPtr, bytesPtr, numBytes);
133 bp->inPtr += numBytes;
134 bp->left -= numBytes;
984263bc 135
1e609a21
MO
136 /*
137 * Null-terminate
138 */
139 *bp->inPtr = 0;
984263bc 140}
fbfaa208 141
984263bc
MD
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 */
155void
6a3d9147 156Buf_UngetByte(Buffer *bp, Byte byte)
984263bc
MD
157{
158
1e609a21
MO
159 if (bp->outPtr != bp->buffer) {
160 bp->outPtr--;
161 *bp->outPtr = byte;
162
163 } else if (bp->outPtr == bp->inPtr) {
164 *bp->inPtr = byte;
165 bp->inPtr++;
166 bp->left--;
167 *bp->inPtr = 0;
168
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 */
4f762dd1 176 size_t numBytes = bp->inPtr - bp->outPtr;
1e609a21
MO
177 Byte *newBuf;
178
179 newBuf = emalloc(bp->size + BUF_UNGET_INC);
180 memcpy(newBuf + BUF_UNGET_INC, bp->outPtr, numBytes + 1);
181 bp->outPtr = newBuf + BUF_UNGET_INC;
182 bp->inPtr = bp->outPtr + numBytes;
183 free(bp->buffer);
184 bp->buffer = newBuf;
185 bp->size += BUF_UNGET_INC;
186 bp->left = bp->size - (bp->inPtr - bp->buffer);
187 bp->outPtr -= 1;
188 *bp->outPtr = byte;
189 }
984263bc 190}
fbfaa208 191
984263bc
MD
192/*-
193 *-----------------------------------------------------------------------
194 * Buf_UngetBytes --
195 * Push back a series of bytes at the beginning of the buffer.
196 *
197 * Results:
198 * None.
199 *
200 * Side Effects:
201 * outPtr is decremented and the bytes copied into the buffer.
202 *
203 *-----------------------------------------------------------------------
204 */
205void
6a3d9147 206Buf_UngetBytes(Buffer *bp, size_t numBytes, Byte *bytesPtr)
984263bc
MD
207{
208
4f762dd1 209 if ((size_t)(bp->outPtr - bp->buffer) >= numBytes) {
1e609a21
MO
210 bp->outPtr -= numBytes;
211 memcpy(bp->outPtr, bytesPtr, numBytes);
212 } else if (bp->outPtr == bp->inPtr) {
213 Buf_AddBytes(bp, numBytes, bytesPtr);
214 } else {
4f762dd1 215 size_t curNumBytes = bp->inPtr - bp->outPtr;
1e609a21 216 Byte *newBuf;
4f762dd1 217 size_t newBytes = max(numBytes, BUF_UNGET_INC);
1e609a21
MO
218
219 newBuf = emalloc(bp->size + newBytes);
220 memcpy(newBuf + newBytes, bp->outPtr, curNumBytes + 1);
221 bp->outPtr = newBuf + newBytes;
222 bp->inPtr = bp->outPtr + curNumBytes;
223 free(bp->buffer);
224 bp->buffer = newBuf;
225 bp->size += newBytes;
226 bp->left = bp->size - (bp->inPtr - bp->buffer);
227 bp->outPtr -= numBytes;
228 memcpy(bp->outPtr, bytesPtr, numBytes);
229 }
984263bc 230}
fbfaa208 231
984263bc
MD
232/*-
233 *-----------------------------------------------------------------------
234 * Buf_GetByte --
235 * Return the next byte from the buffer. Actually returns an integer.
236 *
237 * Results:
238 * Returns BUF_ERROR if there's no byte in the buffer, or the byte
239 * itself if there is one.
240 *
241 * Side Effects:
242 * outPtr is incremented and both outPtr and inPtr will be reset if
243 * the buffer is emptied.
244 *
245 *-----------------------------------------------------------------------
246 */
247int
6a3d9147 248Buf_GetByte(Buffer *bp)
984263bc 249{
1e609a21
MO
250 int res;
251
252 if (bp->inPtr == bp->outPtr)
253 return (BUF_ERROR);
984263bc 254
fbfaa208 255 res = (int)*bp->outPtr;
984263bc
MD
256 bp->outPtr += 1;
257 if (bp->outPtr == bp->inPtr) {
1e609a21
MO
258 bp->outPtr = bp->inPtr = bp->buffer;
259 bp->left = bp->size;
260 *bp->inPtr = 0;
984263bc
MD
261 }
262 return (res);
984263bc 263}
fbfaa208 264
984263bc
MD
265/*-
266 *-----------------------------------------------------------------------
267 * Buf_GetBytes --
268 * Extract a number of bytes from the buffer.
269 *
270 * Results:
271 * The number of bytes gotten.
272 *
273 * Side Effects:
274 * The passed array is overwritten.
275 *
276 *-----------------------------------------------------------------------
277 */
278int
6a3d9147 279Buf_GetBytes(Buffer *bp, size_t numBytes, Byte *bytesPtr)
984263bc
MD
280{
281
4f762dd1 282 if ((size_t)(bp->inPtr - bp->outPtr) < numBytes)
1e609a21 283 numBytes = bp->inPtr - bp->outPtr;
984263bc 284
1e609a21
MO
285 memcpy(bytesPtr, bp->outPtr, numBytes);
286 bp->outPtr += numBytes;
287
288 if (bp->outPtr == bp->inPtr) {
289 bp->outPtr = bp->inPtr = bp->buffer;
290 bp->left = bp->size;
291 *bp->inPtr = 0;
292 }
293 return (numBytes);
984263bc 294}
fbfaa208 295
984263bc
MD
296/*-
297 *-----------------------------------------------------------------------
298 * Buf_GetAll --
299 * Get all the available data at once.
300 *
301 * Results:
302 * A pointer to the data and the number of bytes available.
303 *
304 * Side Effects:
305 * None.
306 *
307 *-----------------------------------------------------------------------
308 */
309Byte *
6a3d9147 310Buf_GetAll(Buffer *bp, size_t *numBytesPtr)
984263bc
MD
311{
312
1e609a21
MO
313 if (numBytesPtr != NULL)
314 *numBytesPtr = bp->inPtr - bp->outPtr;
984263bc 315
1e609a21 316 return (bp->outPtr);
984263bc 317}
fbfaa208 318
984263bc
MD
319/*-
320 *-----------------------------------------------------------------------
321 * Buf_Discard --
322 * Throw away bytes in a buffer.
323 *
324 * Results:
325 * None.
326 *
327 * Side Effects:
328 * The bytes are discarded.
329 *
330 *-----------------------------------------------------------------------
331 */
332void
6a3d9147 333Buf_Discard(Buffer *bp, size_t numBytes)
984263bc
MD
334{
335
4f762dd1 336 if ((size_t)(bp->inPtr - bp->outPtr) <= numBytes) {
1e609a21
MO
337 bp->inPtr = bp->outPtr = bp->buffer;
338 bp->left = bp->size;
339 *bp->inPtr = 0;
340 } else
341 bp->outPtr += numBytes;
984263bc 342}
fbfaa208 343
984263bc
MD
344/*-
345 *-----------------------------------------------------------------------
346 * Buf_Size --
347 * Returns the number of bytes in the given buffer. Doesn't include
348 * the null-terminating byte.
349 *
350 * Results:
351 * The number of bytes.
352 *
353 * Side Effects:
354 * None.
355 *
356 *-----------------------------------------------------------------------
357 */
4f762dd1 358size_t
6a3d9147 359Buf_Size(Buffer *buf)
984263bc 360{
9a4c88c2 361
1e609a21 362 return (buf->inPtr - buf->outPtr);
984263bc 363}
fbfaa208 364
984263bc
MD
365/*-
366 *-----------------------------------------------------------------------
367 * Buf_Init --
368 * Initialize a buffer. If no initial size is given, a reasonable
369 * default is used.
370 *
371 * Results:
372 * A buffer to be given to other functions in this library.
373 *
374 * Side Effects:
375 * The buffer is created, the space allocated and pointers
376 * initialized.
377 *
378 *-----------------------------------------------------------------------
379 */
6a3d9147 380Buffer *
4f762dd1 381Buf_Init(size_t size)
984263bc 382{
6a3d9147 383 Buffer *bp; /* New Buffer */
984263bc 384
1e609a21 385 bp = emalloc(sizeof(*bp));
984263bc 386
1e609a21
MO
387 if (size <= 0)
388 size = BUF_DEF_SIZE;
389
390 bp->left = bp->size = size;
391 bp->buffer = emalloc(size);
392 bp->inPtr = bp->outPtr = bp->buffer;
393 *bp->inPtr = 0;
984263bc 394
1e609a21 395 return (bp);
984263bc 396}
fbfaa208 397
984263bc
MD
398/*-
399 *-----------------------------------------------------------------------
400 * Buf_Destroy --
84de9e23 401 * Destroy a buffer, and optionally free its data, too.
984263bc
MD
402 *
403 * Results:
404 * None.
405 *
406 * Side Effects:
407 * The buffer is freed.
408 *
409 *-----------------------------------------------------------------------
410 */
411void
6a3d9147 412Buf_Destroy(Buffer *buf, Boolean freeData)
984263bc
MD
413{
414
1e609a21
MO
415 if (freeData)
416 free(buf->buffer);
417 free(buf);
984263bc 418}
fbfaa208 419
984263bc
MD
420/*-
421 *-----------------------------------------------------------------------
422 * Buf_ReplaceLastByte --
423 * Replace the last byte in a buffer.
424 *
425 * Results:
426 * None.
427 *
428 * Side Effects:
429 * If the buffer was empty intially, then a new byte will be added.
430 * Otherwise, the last byte is overwritten.
431 *
432 *-----------------------------------------------------------------------
433 */
434void
6a3d9147 435Buf_ReplaceLastByte(Buffer *buf, Byte byte)
984263bc 436{
1e609a21
MO
437 if (buf->inPtr == buf->outPtr)
438 Buf_AddByte(buf, byte);
439 else
440 *(buf->inPtr - 1) = byte;
984263bc 441}