buf.c revision 141436
1141104Sharti/*- 2141290Sharti * Copyright (c) 2005 Max Okumoto 394589Sobrien * Copyright (c) 1988, 1989, 1990, 1993 494589Sobrien * The Regents of the University of California. All rights reserved. 55814Sjkh * Copyright (c) 1988, 1989 by Adam de Boor 61590Srgrimes * Copyright (c) 1989 by Berkeley Softworks 71590Srgrimes * All rights reserved. 81590Srgrimes * 91590Srgrimes * This code is derived from software contributed to Berkeley by 101590Srgrimes * Adam de Boor. 111590Srgrimes * 121590Srgrimes * Redistribution and use in source and binary forms, with or without 131590Srgrimes * modification, are permitted provided that the following conditions 141590Srgrimes * are met: 151590Srgrimes * 1. Redistributions of source code must retain the above copyright 161590Srgrimes * notice, this list of conditions and the following disclaimer. 171590Srgrimes * 2. Redistributions in binary form must reproduce the above copyright 181590Srgrimes * notice, this list of conditions and the following disclaimer in the 191590Srgrimes * documentation and/or other materials provided with the distribution. 201590Srgrimes * 3. All advertising materials mentioning features or use of this software 211590Srgrimes * must display the following acknowledgement: 221590Srgrimes * This product includes software developed by the University of 231590Srgrimes * California, Berkeley and its contributors. 241590Srgrimes * 4. Neither the name of the University nor the names of its contributors 251590Srgrimes * may be used to endorse or promote products derived from this software 261590Srgrimes * without specific prior written permission. 271590Srgrimes * 281590Srgrimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 291590Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 301590Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 311590Srgrimes * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 321590Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 331590Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 341590Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 351590Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 361590Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 371590Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 381590Srgrimes * SUCH DAMAGE. 3962833Swsanchez * 4062833Swsanchez * @(#)buf.c 8.1 (Berkeley) 6/6/93 411590Srgrimes */ 421590Srgrimes 4362833Swsanchez#include <sys/cdefs.h> 4494587Sobrien__FBSDID("$FreeBSD: head/usr.bin/make/buf.c 141436 2005-02-07 07:49:16Z harti $"); 451590Srgrimes 46141290Sharti/* 47141290Sharti * buf.c 481590Srgrimes * Functions for automatically-expanded buffers. 491590Srgrimes */ 501590Srgrimes 51141104Sharti#include <string.h> 52141104Sharti#include <stdlib.h> 53141104Sharti 54141104Sharti#include "buf.h" 55138337Sharti#include "sprite.h" 56141104Sharti#include "util.h" 571590Srgrimes 58141290Sharti#ifndef MAX 59141290Sharti#define MAX(a,b) ((a) > (b) ? (a) : (b)) 601590Srgrimes#endif 611590Srgrimes 62141290Sharti/** 63141290Sharti * Returns the number of bytes in the buffer. Doesn't include the 64141290Sharti * null-terminating byte. 651590Srgrimes */ 66141290Shartiinline size_t 67141290ShartiBuf_Size(const Buffer *buf) 68141290Sharti{ 691590Srgrimes 70141290Sharti return (buf->end - buf->buf); 71141290Sharti} 721590Srgrimes 73141290Sharti/** 74141290Sharti * Expand the buffer to hold the number of additional bytes, plus 75141290Sharti * space to store a terminating NULL byte. 761590Srgrimes */ 77141290Shartistatic inline void 78141290ShartiBufExpand(Buffer *bp, size_t nb) 791590Srgrimes{ 80141290Sharti size_t len = Buf_Size(bp); 81141290Sharti size_t size; 82138264Sharti 83141290Sharti if (bp->size < len + nb + 1) { 84141290Sharti size = bp->size + MAX(nb + 1, BUF_ADD_INC); 85141290Sharti bp->size = size; 86141290Sharti bp->buf = erealloc(bp->buf, size); 87141290Sharti bp->end = bp->buf + len; 88141290Sharti } 891590Srgrimes} 90138232Sharti 91141290Sharti/** 92141290Sharti * Add a single byte to the buffer. 931590Srgrimes */ 94141290Shartiinline void 95141290ShartiBuf_AddByte(Buffer *bp, Byte byte) 961590Srgrimes{ 971590Srgrimes 98141290Sharti BufExpand(bp, 1); 991590Srgrimes 100141290Sharti *bp->end = byte; 101141290Sharti bp->end++; 102141290Sharti *bp->end = '\0'; 1031590Srgrimes} 104138232Sharti 105141290Sharti/** 106141290Sharti * Add bytes to the buffer. 1071590Srgrimes */ 108141290Shartivoid 109141290ShartiBuf_AddBytes(Buffer *bp, size_t len, const Byte *bytes) 1101590Srgrimes{ 1111590Srgrimes 112141290Sharti BufExpand(bp, len); 1138874Srgrimes 114141290Sharti memcpy(bp->end, bytes, len); 115141290Sharti bp->end += len; 116141290Sharti *bp->end = '\0'; 1171590Srgrimes} 118138232Sharti 119141290Sharti/** 120141290Sharti * Get a reference to the internal buffer. 1211590Srgrimes * 122141290Sharti * len: 123141290Sharti * Pointer to where we return the number of bytes in the internal buffer. 1241590Srgrimes * 125141290Sharti * Returns: 126141290Sharti * return A pointer to the data. 1271590Srgrimes */ 128141290ShartiByte * 129141290ShartiBuf_GetAll(Buffer *bp, size_t *len) 1301590Srgrimes{ 131138264Sharti 132141290Sharti if (len != NULL) 133141290Sharti *len = Buf_Size(bp); 134141290Sharti 135141290Sharti return (bp->buf); 1361590Srgrimes} 137138232Sharti 138141290Sharti/** 139141290Sharti * Initialize a buffer. If no initial size is given, a reasonable 140141290Sharti * default is used. 1411590Srgrimes * 142141290Sharti * Returns: 143141290Sharti * A buffer object to be given to other functions in this library. 1441590Srgrimes * 1451590Srgrimes * Side Effects: 146141290Sharti * Space is allocated for the Buffer object and a internal buffer. 1471590Srgrimes */ 148141133ShartiBuffer * 149138341ShartiBuf_Init(size_t size) 1501590Srgrimes{ 151141290Sharti Buffer *bp; /* New Buffer */ 1521590Srgrimes 153138337Sharti if (size <= 0) 154138337Sharti size = BUF_DEF_SIZE; 1551590Srgrimes 156141290Sharti bp = emalloc(sizeof(*bp)); 157141290Sharti bp->size = size; 158141290Sharti bp->buf = emalloc(size); 159141290Sharti bp->end = bp->buf; 160141290Sharti *bp->end = '\0'; 161138337Sharti 162138337Sharti return (bp); 1631590Srgrimes} 164138232Sharti 165141290Sharti/** 166141290Sharti * Destroy a buffer, and optionally free its data, too. 1671590Srgrimes * 1681590Srgrimes * Side Effects: 169141290Sharti * Space for the Buffer object and possibly the internal buffer 170141290Sharti * is de-allocated. 1711590Srgrimes */ 1721590Srgrimesvoid 173141133ShartiBuf_Destroy(Buffer *buf, Boolean freeData) 1741590Srgrimes{ 1758874Srgrimes 176138337Sharti if (freeData) 177141290Sharti free(buf->buf); 178138337Sharti free(buf); 1791590Srgrimes} 180138232Sharti 181141290Sharti/** 182141290Sharti * Replace the last byte in a buffer. If the buffer was empty 183141290Sharti * intially, then a new byte will be added. 18418456Ssteve */ 18518456Sstevevoid 186141290ShartiBuf_ReplaceLastByte(Buffer *bp, Byte byte) 18718456Ssteve{ 188141290Sharti 189141290Sharti if (bp->end == bp->buf) { 190141290Sharti Buf_AddByte(bp, byte); 191141290Sharti } else { 192141290Sharti *(bp->end - 1) = byte; 193141290Sharti } 19418456Ssteve} 195141275Sharti 196141290Sharti/** 197141436Sharti * Append characters in str to Buffer object 198141436Sharti */ 199141436Shartivoid 200141436ShartiBuf_Append(Buffer *bp, const char str[]) 201141436Sharti{ 202141436Sharti 203141436Sharti Buf_AddBytes(bp, strlen(str), str); 204141436Sharti} 205141436Sharti 206141436Sharti/** 207141290Sharti * Clear the contents of the buffer. 208141290Sharti */ 209141275Shartivoid 210141275ShartiBuf_Clear(Buffer *bp) 211141275Sharti{ 212141290Sharti 213141290Sharti bp->end = bp->buf; 214141290Sharti *bp->end = '\0'; 215141275Sharti} 216