Home | History | Annotate | Line # | Download | only in make
buf.c revision 1.26
      1 /*	$NetBSD: buf.c,v 1.26 2020/07/03 08:02:55 rillig Exp $	*/
      2 
      3 /*
      4  * Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
      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. Neither the name of the University nor the names of its contributors
     19  *    may be used to endorse or promote products derived from this software
     20  *    without specific prior written permission.
     21  *
     22  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
     23  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     24  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     25  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
     26  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     27  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     28  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     29  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     30  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     31  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     32  * SUCH DAMAGE.
     33  */
     34 
     35 /*
     36  * Copyright (c) 1988, 1989 by Adam de Boor
     37  * Copyright (c) 1989 by Berkeley Softworks
     38  * All rights reserved.
     39  *
     40  * This code is derived from software contributed to Berkeley by
     41  * Adam de Boor.
     42  *
     43  * Redistribution and use in source and binary forms, with or without
     44  * modification, are permitted provided that the following conditions
     45  * are met:
     46  * 1. Redistributions of source code must retain the above copyright
     47  *    notice, this list of conditions and the following disclaimer.
     48  * 2. Redistributions in binary form must reproduce the above copyright
     49  *    notice, this list of conditions and the following disclaimer in the
     50  *    documentation and/or other materials provided with the distribution.
     51  * 3. All advertising materials mentioning features or use of this software
     52  *    must display the following acknowledgement:
     53  *	This product includes software developed by the University of
     54  *	California, Berkeley and its contributors.
     55  * 4. Neither the name of the University nor the names of its contributors
     56  *    may be used to endorse or promote products derived from this software
     57  *    without specific prior written permission.
     58  *
     59  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
     60  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     61  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     62  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
     63  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     64  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     65  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     66  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     67  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     68  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     69  * SUCH DAMAGE.
     70  */
     71 
     72 #ifndef MAKE_NATIVE
     73 static char rcsid[] = "$NetBSD: buf.c,v 1.26 2020/07/03 08:02:55 rillig Exp $";
     74 #else
     75 #include <sys/cdefs.h>
     76 #ifndef lint
     77 #if 0
     78 static char sccsid[] = "@(#)buf.c	8.1 (Berkeley) 6/6/93";
     79 #else
     80 __RCSID("$NetBSD: buf.c,v 1.26 2020/07/03 08:02:55 rillig Exp $");
     81 #endif
     82 #endif /* not lint */
     83 #endif
     84 
     85 /*-
     86  * buf.c --
     87  *	Functions for automatically-expanded buffers.
     88  */
     89 
     90 #include    "make.h"
     91 #include    "buf.h"
     92 
     93 #ifndef max
     94 #define max(a,b)  ((a) > (b) ? (a) : (b))
     95 #endif
     96 
     97 #define BUF_DEF_SIZE	256 	/* Default buffer size */
     98 
     99 /*-
    100  *-----------------------------------------------------------------------
    101  * Buf_Expand_1 --
    102  *	Extend buffer for single byte add.
    103  *
    104  *-----------------------------------------------------------------------
    105  */
    106 void
    107 Buf_Expand_1(Buffer *bp)
    108 {
    109     bp->size += max(bp->size, 16);
    110     bp->buffer = bmake_realloc(bp->buffer, bp->size);
    111 }
    112 
    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  */
    126 void
    127 Buf_AddBytes(Buffer *bp, int numBytes, const Byte *bytesPtr)
    128 {
    129     int count = bp->count;
    130     Byte *ptr;
    131 
    132     if (__predict_false(count + numBytes >= bp->size)) {
    133 	bp->size += max(bp->size, numBytes + 16);
    134 	bp->buffer = bmake_realloc(bp->buffer, bp->size);
    135     }
    136 
    137     ptr = bp->buffer + count;
    138     bp->count = count + numBytes;
    139     ptr[numBytes] = 0;
    140     memcpy(ptr, bytesPtr, numBytes);
    141 }
    142 
    143 /*-
    144  *-----------------------------------------------------------------------
    145  * Buf_GetAll --
    146  *	Get all the available data at once.
    147  *
    148  * Results:
    149  *	A pointer to the data and the number of bytes available.
    150  *
    151  * Side Effects:
    152  *	None.
    153  *
    154  *-----------------------------------------------------------------------
    155  */
    156 Byte *
    157 Buf_GetAll(Buffer *bp, int *numBytesPtr)
    158 {
    159 
    160     if (numBytesPtr != NULL)
    161 	*numBytesPtr = bp->count;
    162 
    163     return bp->buffer;
    164 }
    165 
    166 /*-
    167  *-----------------------------------------------------------------------
    168  * Buf_Empty --
    169  *	Throw away bytes in a buffer.
    170  *
    171  * Results:
    172  *	None.
    173  *
    174  * Side Effects:
    175  *	The bytes are discarded.
    176  *
    177  *-----------------------------------------------------------------------
    178  */
    179 void
    180 Buf_Empty(Buffer *bp)
    181 {
    182 
    183     bp->count = 0;
    184     *bp->buffer = 0;
    185 }
    186 
    187 /*-
    188  *-----------------------------------------------------------------------
    189  * Buf_Init --
    190  *	Initialize a buffer. If no initial size is given, a reasonable
    191  *	default is used.
    192  *
    193  * Input:
    194  *	size		Initial size for the buffer
    195  *
    196  * Results:
    197  *	A buffer to be given to other functions in this library.
    198  *
    199  * Side Effects:
    200  *	The buffer is created, the space allocated and pointers
    201  *	initialized.
    202  *
    203  *-----------------------------------------------------------------------
    204  */
    205 void
    206 Buf_Init(Buffer *bp, int size)
    207 {
    208     if (size <= 0) {
    209 	size = BUF_DEF_SIZE;
    210     }
    211     bp->size = size;
    212     bp->count = 0;
    213     bp->buffer = bmake_malloc(size);
    214     *bp->buffer = 0;
    215 }
    216 
    217 /*-
    218  *-----------------------------------------------------------------------
    219  * Buf_Destroy --
    220  *	Nuke a buffer and all its resources.
    221  *
    222  * Input:
    223  *	buf		Buffer to destroy
    224  *	freeData	TRUE if the data should be destroyed
    225  *
    226  * Results:
    227  *	Data buffer, NULL if freed
    228  *
    229  * Side Effects:
    230  *	The buffer is freed.
    231  *
    232  *-----------------------------------------------------------------------
    233  */
    234 Byte *
    235 Buf_Destroy(Buffer *buf, Boolean freeData)
    236 {
    237     Byte *data;
    238 
    239     data = buf->buffer;
    240     if (freeData) {
    241 	free(data);
    242 	data = NULL;
    243     }
    244 
    245     buf->size = 0;
    246     buf->count = 0;
    247     buf->buffer = NULL;
    248 
    249     return data;
    250 }
    251 
    252 
    253 /*-
    254  *-----------------------------------------------------------------------
    255  * Buf_DestroyCompact --
    256  *	Nuke a buffer and return its data.
    257  *
    258  * Input:
    259  *	buf		Buffer to destroy
    260  *
    261  * Results:
    262  *	Data buffer
    263  *
    264  * Side Effects:
    265  *	If the buffer size is much greater than its content,
    266  *	a new buffer will be allocated and the old one freed.
    267  *
    268  *-----------------------------------------------------------------------
    269  */
    270 #ifndef BUF_COMPACT_LIMIT
    271 # define BUF_COMPACT_LIMIT 128          /* worthwhile saving */
    272 #endif
    273 
    274 Byte *
    275 Buf_DestroyCompact(Buffer *buf)
    276 {
    277 #if BUF_COMPACT_LIMIT > 0
    278     Byte *data;
    279 
    280     if (buf->size - buf->count >= BUF_COMPACT_LIMIT) {
    281 	/* We trust realloc to be smart */
    282 	data = bmake_realloc(buf->buffer, buf->count + 1);
    283 	if (data) {
    284 	    data[buf->count] = 0;
    285 	    Buf_Destroy(buf, FALSE);
    286 	    return data;
    287 	}
    288     }
    289 #endif
    290     return Buf_Destroy(buf, FALSE);
    291 }
    292