xref: /minix3/usr.bin/make/buf.c (revision 2bc7c627ace37c52ea76fc2f2c700c563df69735)
1*2bc7c627SLionel Sambuc /*	$NetBSD: buf.c,v 1.25 2012/04/24 20:26:58 sjg Exp $	*/
22e2caf59SThomas Veerman 
32e2caf59SThomas Veerman /*
42e2caf59SThomas Veerman  * Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
52e2caf59SThomas Veerman  * All rights reserved.
62e2caf59SThomas Veerman  *
72e2caf59SThomas Veerman  * This code is derived from software contributed to Berkeley by
82e2caf59SThomas Veerman  * Adam de Boor.
92e2caf59SThomas Veerman  *
102e2caf59SThomas Veerman  * Redistribution and use in source and binary forms, with or without
112e2caf59SThomas Veerman  * modification, are permitted provided that the following conditions
122e2caf59SThomas Veerman  * are met:
132e2caf59SThomas Veerman  * 1. Redistributions of source code must retain the above copyright
142e2caf59SThomas Veerman  *    notice, this list of conditions and the following disclaimer.
152e2caf59SThomas Veerman  * 2. Redistributions in binary form must reproduce the above copyright
162e2caf59SThomas Veerman  *    notice, this list of conditions and the following disclaimer in the
172e2caf59SThomas Veerman  *    documentation and/or other materials provided with the distribution.
182e2caf59SThomas Veerman  * 3. Neither the name of the University nor the names of its contributors
192e2caf59SThomas Veerman  *    may be used to endorse or promote products derived from this software
202e2caf59SThomas Veerman  *    without specific prior written permission.
212e2caf59SThomas Veerman  *
222e2caf59SThomas Veerman  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
232e2caf59SThomas Veerman  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
242e2caf59SThomas Veerman  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
252e2caf59SThomas Veerman  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
262e2caf59SThomas Veerman  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
272e2caf59SThomas Veerman  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
282e2caf59SThomas Veerman  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
292e2caf59SThomas Veerman  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
302e2caf59SThomas Veerman  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
312e2caf59SThomas Veerman  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
322e2caf59SThomas Veerman  * SUCH DAMAGE.
332e2caf59SThomas Veerman  */
342e2caf59SThomas Veerman 
352e2caf59SThomas Veerman /*
362e2caf59SThomas Veerman  * Copyright (c) 1988, 1989 by Adam de Boor
372e2caf59SThomas Veerman  * Copyright (c) 1989 by Berkeley Softworks
382e2caf59SThomas Veerman  * All rights reserved.
392e2caf59SThomas Veerman  *
402e2caf59SThomas Veerman  * This code is derived from software contributed to Berkeley by
412e2caf59SThomas Veerman  * Adam de Boor.
422e2caf59SThomas Veerman  *
432e2caf59SThomas Veerman  * Redistribution and use in source and binary forms, with or without
442e2caf59SThomas Veerman  * modification, are permitted provided that the following conditions
452e2caf59SThomas Veerman  * are met:
462e2caf59SThomas Veerman  * 1. Redistributions of source code must retain the above copyright
472e2caf59SThomas Veerman  *    notice, this list of conditions and the following disclaimer.
482e2caf59SThomas Veerman  * 2. Redistributions in binary form must reproduce the above copyright
492e2caf59SThomas Veerman  *    notice, this list of conditions and the following disclaimer in the
502e2caf59SThomas Veerman  *    documentation and/or other materials provided with the distribution.
512e2caf59SThomas Veerman  * 3. All advertising materials mentioning features or use of this software
522e2caf59SThomas Veerman  *    must display the following acknowledgement:
532e2caf59SThomas Veerman  *	This product includes software developed by the University of
542e2caf59SThomas Veerman  *	California, Berkeley and its contributors.
552e2caf59SThomas Veerman  * 4. Neither the name of the University nor the names of its contributors
562e2caf59SThomas Veerman  *    may be used to endorse or promote products derived from this software
572e2caf59SThomas Veerman  *    without specific prior written permission.
582e2caf59SThomas Veerman  *
592e2caf59SThomas Veerman  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
602e2caf59SThomas Veerman  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
612e2caf59SThomas Veerman  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
622e2caf59SThomas Veerman  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
632e2caf59SThomas Veerman  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
642e2caf59SThomas Veerman  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
652e2caf59SThomas Veerman  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
662e2caf59SThomas Veerman  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
672e2caf59SThomas Veerman  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
682e2caf59SThomas Veerman  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
692e2caf59SThomas Veerman  * SUCH DAMAGE.
702e2caf59SThomas Veerman  */
712e2caf59SThomas Veerman 
722e2caf59SThomas Veerman #ifndef MAKE_NATIVE
73*2bc7c627SLionel Sambuc static char rcsid[] = "$NetBSD: buf.c,v 1.25 2012/04/24 20:26:58 sjg Exp $";
742e2caf59SThomas Veerman #else
752e2caf59SThomas Veerman #include <sys/cdefs.h>
762e2caf59SThomas Veerman #ifndef lint
772e2caf59SThomas Veerman #if 0
782e2caf59SThomas Veerman static char sccsid[] = "@(#)buf.c	8.1 (Berkeley) 6/6/93";
792e2caf59SThomas Veerman #else
80*2bc7c627SLionel Sambuc __RCSID("$NetBSD: buf.c,v 1.25 2012/04/24 20:26:58 sjg Exp $");
812e2caf59SThomas Veerman #endif
822e2caf59SThomas Veerman #endif /* not lint */
832e2caf59SThomas Veerman #endif
842e2caf59SThomas Veerman 
852e2caf59SThomas Veerman /*-
862e2caf59SThomas Veerman  * buf.c --
872e2caf59SThomas Veerman  *	Functions for automatically-expanded buffers.
882e2caf59SThomas Veerman  */
892e2caf59SThomas Veerman 
902e2caf59SThomas Veerman #include    "make.h"
912e2caf59SThomas Veerman #include    "buf.h"
922e2caf59SThomas Veerman 
932e2caf59SThomas Veerman #ifndef max
942e2caf59SThomas Veerman #define max(a,b)  ((a) > (b) ? (a) : (b))
952e2caf59SThomas Veerman #endif
962e2caf59SThomas Veerman 
972e2caf59SThomas Veerman #define BUF_DEF_SIZE	256 	/* Default buffer size */
982e2caf59SThomas Veerman 
992e2caf59SThomas Veerman /*-
1002e2caf59SThomas Veerman  *-----------------------------------------------------------------------
1012e2caf59SThomas Veerman  * Buf_Expand_1 --
1022e2caf59SThomas Veerman  *	Extend buffer for single byte add.
1032e2caf59SThomas Veerman  *
1042e2caf59SThomas Veerman  *-----------------------------------------------------------------------
1052e2caf59SThomas Veerman  */
1062e2caf59SThomas Veerman void
Buf_Expand_1(Buffer * bp)1072e2caf59SThomas Veerman Buf_Expand_1(Buffer *bp)
1082e2caf59SThomas Veerman {
1092e2caf59SThomas Veerman     bp->size += max(bp->size, 16);
1102e2caf59SThomas Veerman     bp->buffer = bmake_realloc(bp->buffer, bp->size);
1112e2caf59SThomas Veerman }
1122e2caf59SThomas Veerman 
1132e2caf59SThomas Veerman /*-
1142e2caf59SThomas Veerman  *-----------------------------------------------------------------------
1152e2caf59SThomas Veerman  * Buf_AddBytes --
1162e2caf59SThomas Veerman  *	Add a number of bytes to the buffer.
1172e2caf59SThomas Veerman  *
1182e2caf59SThomas Veerman  * Results:
1192e2caf59SThomas Veerman  *	None.
1202e2caf59SThomas Veerman  *
1212e2caf59SThomas Veerman  * Side Effects:
1222e2caf59SThomas Veerman  *	Guess what?
1232e2caf59SThomas Veerman  *
1242e2caf59SThomas Veerman  *-----------------------------------------------------------------------
1252e2caf59SThomas Veerman  */
1262e2caf59SThomas Veerman void
Buf_AddBytes(Buffer * bp,int numBytes,const Byte * bytesPtr)1272e2caf59SThomas Veerman Buf_AddBytes(Buffer *bp, int numBytes, const Byte *bytesPtr)
1282e2caf59SThomas Veerman {
1292e2caf59SThomas Veerman     int count = bp->count;
1302e2caf59SThomas Veerman     Byte *ptr;
1312e2caf59SThomas Veerman 
1322e2caf59SThomas Veerman     if (__predict_false(count + numBytes >= bp->size)) {
1332e2caf59SThomas Veerman 	bp->size += max(bp->size, numBytes + 16);
1342e2caf59SThomas Veerman 	bp->buffer = bmake_realloc(bp->buffer, bp->size);
1352e2caf59SThomas Veerman     }
1362e2caf59SThomas Veerman 
1372e2caf59SThomas Veerman     ptr = bp->buffer + count;
1382e2caf59SThomas Veerman     bp->count = count + numBytes;
1392e2caf59SThomas Veerman     ptr[numBytes] = 0;
1402e2caf59SThomas Veerman     memcpy(ptr, bytesPtr, numBytes);
1412e2caf59SThomas Veerman }
1422e2caf59SThomas Veerman 
1432e2caf59SThomas Veerman /*-
1442e2caf59SThomas Veerman  *-----------------------------------------------------------------------
1452e2caf59SThomas Veerman  * Buf_GetAll --
1462e2caf59SThomas Veerman  *	Get all the available data at once.
1472e2caf59SThomas Veerman  *
1482e2caf59SThomas Veerman  * Results:
1492e2caf59SThomas Veerman  *	A pointer to the data and the number of bytes available.
1502e2caf59SThomas Veerman  *
1512e2caf59SThomas Veerman  * Side Effects:
1522e2caf59SThomas Veerman  *	None.
1532e2caf59SThomas Veerman  *
1542e2caf59SThomas Veerman  *-----------------------------------------------------------------------
1552e2caf59SThomas Veerman  */
1562e2caf59SThomas Veerman Byte *
Buf_GetAll(Buffer * bp,int * numBytesPtr)1572e2caf59SThomas Veerman Buf_GetAll(Buffer *bp, int *numBytesPtr)
1582e2caf59SThomas Veerman {
1592e2caf59SThomas Veerman 
1602e2caf59SThomas Veerman     if (numBytesPtr != NULL)
1612e2caf59SThomas Veerman 	*numBytesPtr = bp->count;
1622e2caf59SThomas Veerman 
1632e2caf59SThomas Veerman     return (bp->buffer);
1642e2caf59SThomas Veerman }
1652e2caf59SThomas Veerman 
1662e2caf59SThomas Veerman /*-
1672e2caf59SThomas Veerman  *-----------------------------------------------------------------------
1682e2caf59SThomas Veerman  * Buf_Empty --
1692e2caf59SThomas Veerman  *	Throw away bytes in a buffer.
1702e2caf59SThomas Veerman  *
1712e2caf59SThomas Veerman  * Results:
1722e2caf59SThomas Veerman  *	None.
1732e2caf59SThomas Veerman  *
1742e2caf59SThomas Veerman  * Side Effects:
1752e2caf59SThomas Veerman  *	The bytes are discarded.
1762e2caf59SThomas Veerman  *
1772e2caf59SThomas Veerman  *-----------------------------------------------------------------------
1782e2caf59SThomas Veerman  */
1792e2caf59SThomas Veerman void
Buf_Empty(Buffer * bp)1802e2caf59SThomas Veerman Buf_Empty(Buffer *bp)
1812e2caf59SThomas Veerman {
1822e2caf59SThomas Veerman 
1832e2caf59SThomas Veerman     bp->count = 0;
1842e2caf59SThomas Veerman     *bp->buffer = 0;
1852e2caf59SThomas Veerman }
1862e2caf59SThomas Veerman 
1872e2caf59SThomas Veerman /*-
1882e2caf59SThomas Veerman  *-----------------------------------------------------------------------
1892e2caf59SThomas Veerman  * Buf_Init --
1902e2caf59SThomas Veerman  *	Initialize a buffer. If no initial size is given, a reasonable
1912e2caf59SThomas Veerman  *	default is used.
1922e2caf59SThomas Veerman  *
1932e2caf59SThomas Veerman  * Input:
1942e2caf59SThomas Veerman  *	size		Initial size for the buffer
1952e2caf59SThomas Veerman  *
1962e2caf59SThomas Veerman  * Results:
1972e2caf59SThomas Veerman  *	A buffer to be given to other functions in this library.
1982e2caf59SThomas Veerman  *
1992e2caf59SThomas Veerman  * Side Effects:
2002e2caf59SThomas Veerman  *	The buffer is created, the space allocated and pointers
2012e2caf59SThomas Veerman  *	initialized.
2022e2caf59SThomas Veerman  *
2032e2caf59SThomas Veerman  *-----------------------------------------------------------------------
2042e2caf59SThomas Veerman  */
2052e2caf59SThomas Veerman void
Buf_Init(Buffer * bp,int size)2062e2caf59SThomas Veerman Buf_Init(Buffer *bp, int size)
2072e2caf59SThomas Veerman {
2082e2caf59SThomas Veerman     if (size <= 0) {
2092e2caf59SThomas Veerman 	size = BUF_DEF_SIZE;
2102e2caf59SThomas Veerman     }
2112e2caf59SThomas Veerman     bp->size = size;
2122e2caf59SThomas Veerman     bp->count = 0;
2132e2caf59SThomas Veerman     bp->buffer = bmake_malloc(size);
2142e2caf59SThomas Veerman     *bp->buffer = 0;
2152e2caf59SThomas Veerman }
2162e2caf59SThomas Veerman 
2172e2caf59SThomas Veerman /*-
2182e2caf59SThomas Veerman  *-----------------------------------------------------------------------
2192e2caf59SThomas Veerman  * Buf_Destroy --
2202e2caf59SThomas Veerman  *	Nuke a buffer and all its resources.
2212e2caf59SThomas Veerman  *
2222e2caf59SThomas Veerman  * Input:
2232e2caf59SThomas Veerman  *	buf		Buffer to destroy
2242e2caf59SThomas Veerman  *	freeData	TRUE if the data should be destroyed
2252e2caf59SThomas Veerman  *
2262e2caf59SThomas Veerman  * Results:
2272e2caf59SThomas Veerman  *	Data buffer, NULL if freed
2282e2caf59SThomas Veerman  *
2292e2caf59SThomas Veerman  * Side Effects:
2302e2caf59SThomas Veerman  *	The buffer is freed.
2312e2caf59SThomas Veerman  *
2322e2caf59SThomas Veerman  *-----------------------------------------------------------------------
2332e2caf59SThomas Veerman  */
2342e2caf59SThomas Veerman Byte *
Buf_Destroy(Buffer * buf,Boolean freeData)2352e2caf59SThomas Veerman Buf_Destroy(Buffer *buf, Boolean freeData)
2362e2caf59SThomas Veerman {
2372e2caf59SThomas Veerman     Byte *data;
2382e2caf59SThomas Veerman 
2392e2caf59SThomas Veerman     data = buf->buffer;
2402e2caf59SThomas Veerman     if (freeData) {
2412e2caf59SThomas Veerman 	free(data);
2422e2caf59SThomas Veerman 	data = NULL;
2432e2caf59SThomas Veerman     }
2442e2caf59SThomas Veerman 
2452e2caf59SThomas Veerman     buf->size = 0;
2462e2caf59SThomas Veerman     buf->count = 0;
2472e2caf59SThomas Veerman     buf->buffer = NULL;
2482e2caf59SThomas Veerman 
2492e2caf59SThomas Veerman     return data;
2502e2caf59SThomas Veerman }
251*2bc7c627SLionel Sambuc 
252*2bc7c627SLionel Sambuc 
253*2bc7c627SLionel Sambuc /*-
254*2bc7c627SLionel Sambuc  *-----------------------------------------------------------------------
255*2bc7c627SLionel Sambuc  * Buf_DestroyCompact --
256*2bc7c627SLionel Sambuc  *	Nuke a buffer and return its data.
257*2bc7c627SLionel Sambuc  *
258*2bc7c627SLionel Sambuc  * Input:
259*2bc7c627SLionel Sambuc  *	buf		Buffer to destroy
260*2bc7c627SLionel Sambuc  *
261*2bc7c627SLionel Sambuc  * Results:
262*2bc7c627SLionel Sambuc  *	Data buffer
263*2bc7c627SLionel Sambuc  *
264*2bc7c627SLionel Sambuc  * Side Effects:
265*2bc7c627SLionel Sambuc  *	If the buffer size is much greater than its content,
266*2bc7c627SLionel Sambuc  *	a new buffer will be allocated and the old one freed.
267*2bc7c627SLionel Sambuc  *
268*2bc7c627SLionel Sambuc  *-----------------------------------------------------------------------
269*2bc7c627SLionel Sambuc  */
270*2bc7c627SLionel Sambuc #ifndef BUF_COMPACT_LIMIT
271*2bc7c627SLionel Sambuc # define BUF_COMPACT_LIMIT 128          /* worthwhile saving */
272*2bc7c627SLionel Sambuc #endif
273*2bc7c627SLionel Sambuc 
274*2bc7c627SLionel Sambuc Byte *
Buf_DestroyCompact(Buffer * buf)275*2bc7c627SLionel Sambuc Buf_DestroyCompact(Buffer *buf)
276*2bc7c627SLionel Sambuc {
277*2bc7c627SLionel Sambuc #if BUF_COMPACT_LIMIT > 0
278*2bc7c627SLionel Sambuc     Byte *data;
279*2bc7c627SLionel Sambuc 
280*2bc7c627SLionel Sambuc     if (buf->size - buf->count >= BUF_COMPACT_LIMIT) {
281*2bc7c627SLionel Sambuc 	/* We trust realloc to be smart */
282*2bc7c627SLionel Sambuc 	data = bmake_realloc(buf->buffer, buf->count + 1);
283*2bc7c627SLionel Sambuc 	if (data) {
284*2bc7c627SLionel Sambuc 	    data[buf->count] = 0;
285*2bc7c627SLionel Sambuc 	    Buf_Destroy(buf, FALSE);
286*2bc7c627SLionel Sambuc 	    return data;
287*2bc7c627SLionel Sambuc 	}
288*2bc7c627SLionel Sambuc     }
289*2bc7c627SLionel Sambuc #endif
290*2bc7c627SLionel Sambuc     return Buf_Destroy(buf, FALSE);
291*2bc7c627SLionel Sambuc }
292