1*2c3632d1SSimon J. Gerraty /* $NetBSD: buf.c,v 1.37 2020/08/23 08:21:50 rillig Exp $ */ 23955d011SMarcel Moolenaar 33955d011SMarcel Moolenaar /* 43955d011SMarcel Moolenaar * Copyright (c) 1988, 1989, 1990 The Regents of the University of California. 53955d011SMarcel Moolenaar * All rights reserved. 63955d011SMarcel Moolenaar * 73955d011SMarcel Moolenaar * This code is derived from software contributed to Berkeley by 83955d011SMarcel Moolenaar * Adam de Boor. 93955d011SMarcel Moolenaar * 103955d011SMarcel Moolenaar * Redistribution and use in source and binary forms, with or without 113955d011SMarcel Moolenaar * modification, are permitted provided that the following conditions 123955d011SMarcel Moolenaar * are met: 133955d011SMarcel Moolenaar * 1. Redistributions of source code must retain the above copyright 143955d011SMarcel Moolenaar * notice, this list of conditions and the following disclaimer. 153955d011SMarcel Moolenaar * 2. Redistributions in binary form must reproduce the above copyright 163955d011SMarcel Moolenaar * notice, this list of conditions and the following disclaimer in the 173955d011SMarcel Moolenaar * documentation and/or other materials provided with the distribution. 183955d011SMarcel Moolenaar * 3. Neither the name of the University nor the names of its contributors 193955d011SMarcel Moolenaar * may be used to endorse or promote products derived from this software 203955d011SMarcel Moolenaar * without specific prior written permission. 213955d011SMarcel Moolenaar * 223955d011SMarcel Moolenaar * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 233955d011SMarcel Moolenaar * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 243955d011SMarcel Moolenaar * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 253955d011SMarcel Moolenaar * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 263955d011SMarcel Moolenaar * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 273955d011SMarcel Moolenaar * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 283955d011SMarcel Moolenaar * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 293955d011SMarcel Moolenaar * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 303955d011SMarcel Moolenaar * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 313955d011SMarcel Moolenaar * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 323955d011SMarcel Moolenaar * SUCH DAMAGE. 333955d011SMarcel Moolenaar */ 343955d011SMarcel Moolenaar 353955d011SMarcel Moolenaar /* 363955d011SMarcel Moolenaar * Copyright (c) 1988, 1989 by Adam de Boor 373955d011SMarcel Moolenaar * Copyright (c) 1989 by Berkeley Softworks 383955d011SMarcel Moolenaar * All rights reserved. 393955d011SMarcel Moolenaar * 403955d011SMarcel Moolenaar * This code is derived from software contributed to Berkeley by 413955d011SMarcel Moolenaar * Adam de Boor. 423955d011SMarcel Moolenaar * 433955d011SMarcel Moolenaar * Redistribution and use in source and binary forms, with or without 443955d011SMarcel Moolenaar * modification, are permitted provided that the following conditions 453955d011SMarcel Moolenaar * are met: 463955d011SMarcel Moolenaar * 1. Redistributions of source code must retain the above copyright 473955d011SMarcel Moolenaar * notice, this list of conditions and the following disclaimer. 483955d011SMarcel Moolenaar * 2. Redistributions in binary form must reproduce the above copyright 493955d011SMarcel Moolenaar * notice, this list of conditions and the following disclaimer in the 503955d011SMarcel Moolenaar * documentation and/or other materials provided with the distribution. 513955d011SMarcel Moolenaar * 3. All advertising materials mentioning features or use of this software 523955d011SMarcel Moolenaar * must display the following acknowledgement: 533955d011SMarcel Moolenaar * This product includes software developed by the University of 543955d011SMarcel Moolenaar * California, Berkeley and its contributors. 553955d011SMarcel Moolenaar * 4. Neither the name of the University nor the names of its contributors 563955d011SMarcel Moolenaar * may be used to endorse or promote products derived from this software 573955d011SMarcel Moolenaar * without specific prior written permission. 583955d011SMarcel Moolenaar * 593955d011SMarcel Moolenaar * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 603955d011SMarcel Moolenaar * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 613955d011SMarcel Moolenaar * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 623955d011SMarcel Moolenaar * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 633955d011SMarcel Moolenaar * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 643955d011SMarcel Moolenaar * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 653955d011SMarcel Moolenaar * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 663955d011SMarcel Moolenaar * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 673955d011SMarcel Moolenaar * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 683955d011SMarcel Moolenaar * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 693955d011SMarcel Moolenaar * SUCH DAMAGE. 703955d011SMarcel Moolenaar */ 713955d011SMarcel Moolenaar 723955d011SMarcel Moolenaar #ifndef MAKE_NATIVE 73*2c3632d1SSimon J. Gerraty static char rcsid[] = "$NetBSD: buf.c,v 1.37 2020/08/23 08:21:50 rillig Exp $"; 743955d011SMarcel Moolenaar #else 753955d011SMarcel Moolenaar #include <sys/cdefs.h> 763955d011SMarcel Moolenaar #ifndef lint 773955d011SMarcel Moolenaar #if 0 783955d011SMarcel Moolenaar static char sccsid[] = "@(#)buf.c 8.1 (Berkeley) 6/6/93"; 793955d011SMarcel Moolenaar #else 80*2c3632d1SSimon J. Gerraty __RCSID("$NetBSD: buf.c,v 1.37 2020/08/23 08:21:50 rillig Exp $"); 813955d011SMarcel Moolenaar #endif 823955d011SMarcel Moolenaar #endif /* not lint */ 833955d011SMarcel Moolenaar #endif 843955d011SMarcel Moolenaar 85*2c3632d1SSimon J. Gerraty /* Functions for automatically-expanded null-terminated buffers. */ 863955d011SMarcel Moolenaar 87*2c3632d1SSimon J. Gerraty #include <limits.h> 883955d011SMarcel Moolenaar #include "make.h" 893955d011SMarcel Moolenaar 90*2c3632d1SSimon J. Gerraty /* Extend the buffer for adding a single byte. */ 913955d011SMarcel Moolenaar void 923955d011SMarcel Moolenaar Buf_Expand_1(Buffer *bp) 933955d011SMarcel Moolenaar { 94*2c3632d1SSimon J. Gerraty bp->size += MAX(bp->size, 16); 953955d011SMarcel Moolenaar bp->buffer = bmake_realloc(bp->buffer, bp->size); 963955d011SMarcel Moolenaar } 973955d011SMarcel Moolenaar 98*2c3632d1SSimon J. Gerraty /* Add the given bytes to the buffer. */ 993955d011SMarcel Moolenaar void 100*2c3632d1SSimon J. Gerraty Buf_AddBytes(Buffer *bp, const char *bytesPtr, size_t numBytes) 1013955d011SMarcel Moolenaar { 102*2c3632d1SSimon J. Gerraty size_t count = bp->count; 103*2c3632d1SSimon J. Gerraty char *ptr; 1043955d011SMarcel Moolenaar 1053955d011SMarcel Moolenaar if (__predict_false(count + numBytes >= bp->size)) { 106*2c3632d1SSimon J. Gerraty bp->size += MAX(bp->size, numBytes + 16); 1073955d011SMarcel Moolenaar bp->buffer = bmake_realloc(bp->buffer, bp->size); 1083955d011SMarcel Moolenaar } 1093955d011SMarcel Moolenaar 1103955d011SMarcel Moolenaar ptr = bp->buffer + count; 1113955d011SMarcel Moolenaar bp->count = count + numBytes; 1123955d011SMarcel Moolenaar memcpy(ptr, bytesPtr, numBytes); 113*2c3632d1SSimon J. Gerraty ptr[numBytes] = '\0'; 1143955d011SMarcel Moolenaar } 1153955d011SMarcel Moolenaar 116*2c3632d1SSimon J. Gerraty /* Add the bytes between start and end to the buffer. */ 117*2c3632d1SSimon J. Gerraty void 118*2c3632d1SSimon J. Gerraty Buf_AddBytesBetween(Buffer *bp, const char *start, const char *end) 1193955d011SMarcel Moolenaar { 120*2c3632d1SSimon J. Gerraty Buf_AddBytes(bp, start, (size_t)(end - start)); 121*2c3632d1SSimon J. Gerraty } 1223955d011SMarcel Moolenaar 123*2c3632d1SSimon J. Gerraty /* Add the given string to the buffer. */ 124*2c3632d1SSimon J. Gerraty void 125*2c3632d1SSimon J. Gerraty Buf_AddStr(Buffer *bp, const char *str) 126*2c3632d1SSimon J. Gerraty { 127*2c3632d1SSimon J. Gerraty Buf_AddBytes(bp, str, strlen(str)); 128*2c3632d1SSimon J. Gerraty } 129*2c3632d1SSimon J. Gerraty 130*2c3632d1SSimon J. Gerraty /* Add the given number to the buffer. */ 131*2c3632d1SSimon J. Gerraty void 132*2c3632d1SSimon J. Gerraty Buf_AddInt(Buffer *bp, int n) 133*2c3632d1SSimon J. Gerraty { 134*2c3632d1SSimon J. Gerraty enum { 135*2c3632d1SSimon J. Gerraty bits = sizeof(int) * CHAR_BIT, 136*2c3632d1SSimon J. Gerraty max_octal_digits = (bits + 2) / 3, 137*2c3632d1SSimon J. Gerraty max_decimal_digits = /* at most */ max_octal_digits, 138*2c3632d1SSimon J. Gerraty max_sign_chars = 1, 139*2c3632d1SSimon J. Gerraty buf_size = max_sign_chars + max_decimal_digits + 1 140*2c3632d1SSimon J. Gerraty }; 141*2c3632d1SSimon J. Gerraty char buf[buf_size]; 142*2c3632d1SSimon J. Gerraty 143*2c3632d1SSimon J. Gerraty size_t len = (size_t)snprintf(buf, sizeof buf, "%d", n); 144*2c3632d1SSimon J. Gerraty Buf_AddBytes(bp, buf, len); 145*2c3632d1SSimon J. Gerraty } 146*2c3632d1SSimon J. Gerraty 147*2c3632d1SSimon J. Gerraty /* Get the data (usually a string) from the buffer. 148*2c3632d1SSimon J. Gerraty * The returned data is valid until the next modifying operation 149*2c3632d1SSimon J. Gerraty * on the buffer. 150*2c3632d1SSimon J. Gerraty * 151*2c3632d1SSimon J. Gerraty * Returns the pointer to the data and optionally the length of the 152*2c3632d1SSimon J. Gerraty * data in the buffer. */ 153*2c3632d1SSimon J. Gerraty char * 154*2c3632d1SSimon J. Gerraty Buf_GetAll(Buffer *bp, size_t *numBytesPtr) 155*2c3632d1SSimon J. Gerraty { 1563955d011SMarcel Moolenaar if (numBytesPtr != NULL) 1573955d011SMarcel Moolenaar *numBytesPtr = bp->count; 1583841c287SSimon J. Gerraty return bp->buffer; 1593955d011SMarcel Moolenaar } 1603955d011SMarcel Moolenaar 161*2c3632d1SSimon J. Gerraty /* Mark the buffer as empty, so it can be filled with data again. */ 1623955d011SMarcel Moolenaar void 1633955d011SMarcel Moolenaar Buf_Empty(Buffer *bp) 1643955d011SMarcel Moolenaar { 1653955d011SMarcel Moolenaar bp->count = 0; 166*2c3632d1SSimon J. Gerraty bp->buffer[0] = '\0'; 1673955d011SMarcel Moolenaar } 1683955d011SMarcel Moolenaar 169*2c3632d1SSimon J. Gerraty /* Initialize a buffer. 170*2c3632d1SSimon J. Gerraty * If the given initial size is 0, a reasonable default is used. */ 1713955d011SMarcel Moolenaar void 172*2c3632d1SSimon J. Gerraty Buf_Init(Buffer *bp, size_t size) 1733955d011SMarcel Moolenaar { 1743955d011SMarcel Moolenaar if (size <= 0) { 175*2c3632d1SSimon J. Gerraty size = 256; 1763955d011SMarcel Moolenaar } 1773955d011SMarcel Moolenaar bp->size = size; 1783955d011SMarcel Moolenaar bp->count = 0; 1793955d011SMarcel Moolenaar bp->buffer = bmake_malloc(size); 180*2c3632d1SSimon J. Gerraty bp->buffer[0] = '\0'; 1813955d011SMarcel Moolenaar } 1823955d011SMarcel Moolenaar 183*2c3632d1SSimon J. Gerraty /* Reset the buffer. 184*2c3632d1SSimon J. Gerraty * If freeData is TRUE, the data from the buffer is freed as well. 185*2c3632d1SSimon J. Gerraty * Otherwise it is kept and returned. */ 186*2c3632d1SSimon J. Gerraty char * 1873955d011SMarcel Moolenaar Buf_Destroy(Buffer *buf, Boolean freeData) 1883955d011SMarcel Moolenaar { 189*2c3632d1SSimon J. Gerraty char *data = buf->buffer; 1903955d011SMarcel Moolenaar if (freeData) { 1913955d011SMarcel Moolenaar free(data); 1923955d011SMarcel Moolenaar data = NULL; 1933955d011SMarcel Moolenaar } 1943955d011SMarcel Moolenaar 1953955d011SMarcel Moolenaar buf->size = 0; 1963955d011SMarcel Moolenaar buf->count = 0; 1973955d011SMarcel Moolenaar buf->buffer = NULL; 1983955d011SMarcel Moolenaar 1993955d011SMarcel Moolenaar return data; 2003955d011SMarcel Moolenaar } 2013955d011SMarcel Moolenaar 2023955d011SMarcel Moolenaar #ifndef BUF_COMPACT_LIMIT 2033955d011SMarcel Moolenaar # define BUF_COMPACT_LIMIT 128 /* worthwhile saving */ 2043955d011SMarcel Moolenaar #endif 2053955d011SMarcel Moolenaar 206*2c3632d1SSimon J. Gerraty /* Reset the buffer and return its data. 207*2c3632d1SSimon J. Gerraty * 208*2c3632d1SSimon J. Gerraty * If the buffer size is much greater than its content, 209*2c3632d1SSimon J. Gerraty * a new buffer will be allocated and the old one freed. */ 210*2c3632d1SSimon J. Gerraty char * 2113955d011SMarcel Moolenaar Buf_DestroyCompact(Buffer *buf) 2123955d011SMarcel Moolenaar { 2133955d011SMarcel Moolenaar #if BUF_COMPACT_LIMIT > 0 2143955d011SMarcel Moolenaar if (buf->size - buf->count >= BUF_COMPACT_LIMIT) { 2153955d011SMarcel Moolenaar /* We trust realloc to be smart */ 216*2c3632d1SSimon J. Gerraty char *data = bmake_realloc(buf->buffer, buf->count + 1); 217*2c3632d1SSimon J. Gerraty data[buf->count] = '\0'; 2183955d011SMarcel Moolenaar Buf_Destroy(buf, FALSE); 2193955d011SMarcel Moolenaar return data; 2203955d011SMarcel Moolenaar } 2213955d011SMarcel Moolenaar #endif 2223955d011SMarcel Moolenaar return Buf_Destroy(buf, FALSE); 2233955d011SMarcel Moolenaar } 224