buf.c revision 141104
1141104Sharti/*- 294589Sobrien * Copyright (c) 1988, 1989, 1990, 1993 394589Sobrien * The Regents of the University of California. All rights reserved. 45814Sjkh * Copyright (c) 1988, 1989 by Adam de Boor 51590Srgrimes * Copyright (c) 1989 by Berkeley Softworks 61590Srgrimes * All rights reserved. 71590Srgrimes * 81590Srgrimes * This code is derived from software contributed to Berkeley by 91590Srgrimes * Adam de Boor. 101590Srgrimes * 111590Srgrimes * Redistribution and use in source and binary forms, with or without 121590Srgrimes * modification, are permitted provided that the following conditions 131590Srgrimes * are met: 141590Srgrimes * 1. Redistributions of source code must retain the above copyright 151590Srgrimes * notice, this list of conditions and the following disclaimer. 161590Srgrimes * 2. Redistributions in binary form must reproduce the above copyright 171590Srgrimes * notice, this list of conditions and the following disclaimer in the 181590Srgrimes * documentation and/or other materials provided with the distribution. 191590Srgrimes * 3. All advertising materials mentioning features or use of this software 201590Srgrimes * must display the following acknowledgement: 211590Srgrimes * This product includes software developed by the University of 221590Srgrimes * California, Berkeley and its contributors. 231590Srgrimes * 4. Neither the name of the University nor the names of its contributors 241590Srgrimes * may be used to endorse or promote products derived from this software 251590Srgrimes * without specific prior written permission. 261590Srgrimes * 271590Srgrimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 281590Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 291590Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 301590Srgrimes * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 311590Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 321590Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 331590Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 341590Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 351590Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 361590Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 371590Srgrimes * SUCH DAMAGE. 3862833Swsanchez * 3962833Swsanchez * @(#)buf.c 8.1 (Berkeley) 6/6/93 401590Srgrimes */ 411590Srgrimes 4262833Swsanchez#include <sys/cdefs.h> 4394587Sobrien__FBSDID("$FreeBSD: head/usr.bin/make/buf.c 141104 2005-02-01 10:50:37Z harti $"); 441590Srgrimes 451590Srgrimes/*- 461590Srgrimes * buf.c -- 471590Srgrimes * Functions for automatically-expanded buffers. 481590Srgrimes */ 491590Srgrimes 50141104Sharti#include <string.h> 51141104Sharti#include <stdlib.h> 52141104Sharti 53141104Sharti#include "buf.h" 54138337Sharti#include "sprite.h" 55141104Sharti#include "util.h" 561590Srgrimes 571590Srgrimes#ifndef max 58103503Sjmallett#define max(a,b) ((a) > (b) ? (a) : (b)) 591590Srgrimes#endif 601590Srgrimes 611590Srgrimes/* 621590Srgrimes * BufExpand -- 631590Srgrimes * Expand the given buffer to hold the given number of additional 641590Srgrimes * bytes. 651590Srgrimes * Makes sure there's room for an extra NULL byte at the end of the 661590Srgrimes * buffer in case it holds a string. 671590Srgrimes */ 68138337Sharti#define BufExpand(bp, nb) do { \ 69138342Sharti if ((bp)->left < (nb) + 1) { \ 70138337Sharti int newSize = (bp)->size + max((nb) + 1, BUF_ADD_INC); \ 71138347Sharti Byte *newBuf = erealloc((bp)->buffer, newSize); \ 72138337Sharti \ 73138337Sharti (bp)->inPtr = newBuf + ((bp)->inPtr - (bp)->buffer); \ 74138337Sharti (bp)->outPtr = newBuf + ((bp)->outPtr - (bp)->buffer); \ 75138337Sharti (bp)->buffer = newBuf; \ 76138337Sharti (bp)->size = newSize; \ 77138337Sharti (bp)->left = newSize - ((bp)->inPtr - (bp)->buffer); \ 78138337Sharti } \ 79138337Sharti } while (0) 801590Srgrimes 81103503Sjmallett#define BUF_DEF_SIZE 256 /* Default buffer size */ 82103503Sjmallett#define BUF_ADD_INC 256 /* Expansion increment when Adding */ 83103503Sjmallett#define BUF_UNGET_INC 16 /* Expansion increment when Ungetting */ 841590Srgrimes 851590Srgrimes/*- 861590Srgrimes *----------------------------------------------------------------------- 871590Srgrimes * Buf_OvAddByte -- 881590Srgrimes * Add a single byte to the buffer. left is zero or negative. 891590Srgrimes * 901590Srgrimes * Results: 911590Srgrimes * None. 921590Srgrimes * 931590Srgrimes * Side Effects: 941590Srgrimes * The buffer may be expanded. 951590Srgrimes * 961590Srgrimes *----------------------------------------------------------------------- 971590Srgrimes */ 981590Srgrimesvoid 99138341ShartiBuf_OvAddByte(Buffer bp, Byte byte) 1001590Srgrimes{ 101138264Sharti 102138337Sharti bp->left = 0; 103138337Sharti BufExpand(bp, 1); 1041590Srgrimes 105138337Sharti *bp->inPtr++ = byte; 106138337Sharti bp->left--; 1071590Srgrimes 108138337Sharti /* 109138337Sharti * Null-terminate 110138337Sharti */ 111138337Sharti *bp->inPtr = 0; 1121590Srgrimes} 113138232Sharti 1141590Srgrimes/*- 1151590Srgrimes *----------------------------------------------------------------------- 1161590Srgrimes * Buf_AddBytes -- 1171590Srgrimes * Add a number of bytes to the buffer. 1181590Srgrimes * 1191590Srgrimes * Results: 1201590Srgrimes * None. 1211590Srgrimes * 1221590Srgrimes * Side Effects: 1231590Srgrimes * Guess what? 1241590Srgrimes * 1251590Srgrimes *----------------------------------------------------------------------- 1261590Srgrimes */ 1271590Srgrimesvoid 128138341ShartiBuf_AddBytes(Buffer bp, size_t numBytes, const Byte *bytesPtr) 1291590Srgrimes{ 1301590Srgrimes 131138337Sharti BufExpand(bp, numBytes); 1321590Srgrimes 133138337Sharti memcpy(bp->inPtr, bytesPtr, numBytes); 134138337Sharti bp->inPtr += numBytes; 135138337Sharti bp->left -= numBytes; 1361590Srgrimes 137138337Sharti /* 138138337Sharti * Null-terminate 139138337Sharti */ 140138337Sharti *bp->inPtr = 0; 1411590Srgrimes} 142138232Sharti 1431590Srgrimes/*- 1441590Srgrimes *----------------------------------------------------------------------- 1451590Srgrimes * Buf_UngetByte -- 1461590Srgrimes * Place the byte back at the beginning of the buffer. 1471590Srgrimes * 1481590Srgrimes * Results: 1491590Srgrimes * SUCCESS if the byte was added ok. FAILURE if not. 1501590Srgrimes * 1511590Srgrimes * Side Effects: 1521590Srgrimes * The byte is stuffed in the buffer and outPtr is decremented. 1531590Srgrimes * 1541590Srgrimes *----------------------------------------------------------------------- 1551590Srgrimes */ 1561590Srgrimesvoid 157138341ShartiBuf_UngetByte(Buffer bp, Byte byte) 1581590Srgrimes{ 1591590Srgrimes 160138337Sharti if (bp->outPtr != bp->buffer) { 161138337Sharti bp->outPtr--; 162138337Sharti *bp->outPtr = byte; 1631590Srgrimes 164138337Sharti } else if (bp->outPtr == bp->inPtr) { 165138337Sharti *bp->inPtr = byte; 166138337Sharti bp->inPtr++; 167138337Sharti bp->left--; 168138337Sharti *bp->inPtr = 0; 169138337Sharti 170138337Sharti } else { 171138337Sharti /* 172138337Sharti * Yech. have to expand the buffer to stuff this thing in. 173138337Sharti * We use a different expansion constant because people don't 174138337Sharti * usually push back many bytes when they're doing it a byte at 175138337Sharti * a time... 176138337Sharti */ 177138341Sharti size_t numBytes = bp->inPtr - bp->outPtr; 178138337Sharti Byte *newBuf; 179138337Sharti 180138337Sharti newBuf = emalloc(bp->size + BUF_UNGET_INC); 181138337Sharti memcpy(newBuf + BUF_UNGET_INC, bp->outPtr, numBytes + 1); 182138337Sharti bp->outPtr = newBuf + BUF_UNGET_INC; 183138337Sharti bp->inPtr = bp->outPtr + numBytes; 184138337Sharti free(bp->buffer); 185138337Sharti bp->buffer = newBuf; 186138337Sharti bp->size += BUF_UNGET_INC; 187138337Sharti bp->left = bp->size - (bp->inPtr - bp->buffer); 188138337Sharti bp->outPtr -= 1; 189138337Sharti *bp->outPtr = byte; 190138337Sharti } 1911590Srgrimes} 192138232Sharti 1931590Srgrimes/*- 1941590Srgrimes *----------------------------------------------------------------------- 1951590Srgrimes * Buf_UngetBytes -- 1961590Srgrimes * Push back a series of bytes at the beginning of the buffer. 1971590Srgrimes * 1981590Srgrimes * Results: 1991590Srgrimes * None. 2001590Srgrimes * 2011590Srgrimes * Side Effects: 2021590Srgrimes * outPtr is decremented and the bytes copied into the buffer. 2031590Srgrimes * 2041590Srgrimes *----------------------------------------------------------------------- 2051590Srgrimes */ 2061590Srgrimesvoid 207138341ShartiBuf_UngetBytes(Buffer bp, size_t numBytes, Byte *bytesPtr) 2081590Srgrimes{ 2091590Srgrimes 210138341Sharti if ((size_t)(bp->outPtr - bp->buffer) >= numBytes) { 211138337Sharti bp->outPtr -= numBytes; 212138337Sharti memcpy(bp->outPtr, bytesPtr, numBytes); 213138337Sharti } else if (bp->outPtr == bp->inPtr) { 214138337Sharti Buf_AddBytes(bp, numBytes, bytesPtr); 215138337Sharti } else { 216138341Sharti size_t curNumBytes = bp->inPtr - bp->outPtr; 217138337Sharti Byte *newBuf; 218138341Sharti size_t newBytes = max(numBytes, BUF_UNGET_INC); 2191590Srgrimes 220138337Sharti newBuf = emalloc(bp->size + newBytes); 221138337Sharti memcpy(newBuf + newBytes, bp->outPtr, curNumBytes + 1); 222138337Sharti bp->outPtr = newBuf + newBytes; 223138337Sharti bp->inPtr = bp->outPtr + curNumBytes; 224138337Sharti free(bp->buffer); 225138337Sharti bp->buffer = newBuf; 226138337Sharti bp->size += newBytes; 227138337Sharti bp->left = bp->size - (bp->inPtr - bp->buffer); 228138337Sharti bp->outPtr -= numBytes; 229138337Sharti memcpy(bp->outPtr, bytesPtr, numBytes); 230138337Sharti } 2311590Srgrimes} 232138232Sharti 2331590Srgrimes/*- 2341590Srgrimes *----------------------------------------------------------------------- 2351590Srgrimes * Buf_GetByte -- 2361590Srgrimes * Return the next byte from the buffer. Actually returns an integer. 2371590Srgrimes * 2381590Srgrimes * Results: 2391590Srgrimes * Returns BUF_ERROR if there's no byte in the buffer, or the byte 2401590Srgrimes * itself if there is one. 2411590Srgrimes * 2421590Srgrimes * Side Effects: 2431590Srgrimes * outPtr is incremented and both outPtr and inPtr will be reset if 2441590Srgrimes * the buffer is emptied. 2451590Srgrimes * 2461590Srgrimes *----------------------------------------------------------------------- 2471590Srgrimes */ 2481590Srgrimesint 249138232ShartiBuf_GetByte(Buffer bp) 2501590Srgrimes{ 251138337Sharti int res; 2521590Srgrimes 253138337Sharti if (bp->inPtr == bp->outPtr) 254138337Sharti return (BUF_ERROR); 255138337Sharti 256138232Sharti res = (int)*bp->outPtr; 2571590Srgrimes bp->outPtr += 1; 2581590Srgrimes if (bp->outPtr == bp->inPtr) { 259138337Sharti bp->outPtr = bp->inPtr = bp->buffer; 260138337Sharti bp->left = bp->size; 261138337Sharti *bp->inPtr = 0; 2621590Srgrimes } 2631590Srgrimes return (res); 2641590Srgrimes} 265138232Sharti 2661590Srgrimes/*- 2671590Srgrimes *----------------------------------------------------------------------- 2681590Srgrimes * Buf_GetBytes -- 2691590Srgrimes * Extract a number of bytes from the buffer. 2701590Srgrimes * 2711590Srgrimes * Results: 2721590Srgrimes * The number of bytes gotten. 2731590Srgrimes * 2741590Srgrimes * Side Effects: 2751590Srgrimes * The passed array is overwritten. 2761590Srgrimes * 2771590Srgrimes *----------------------------------------------------------------------- 2781590Srgrimes */ 2791590Srgrimesint 280138341ShartiBuf_GetBytes(Buffer bp, size_t numBytes, Byte *bytesPtr) 2811590Srgrimes{ 2828874Srgrimes 283138341Sharti if ((size_t)(bp->inPtr - bp->outPtr) < numBytes) 284138337Sharti numBytes = bp->inPtr - bp->outPtr; 2851590Srgrimes 286138337Sharti memcpy(bytesPtr, bp->outPtr, numBytes); 287138337Sharti bp->outPtr += numBytes; 288138337Sharti 289138337Sharti if (bp->outPtr == bp->inPtr) { 290138337Sharti bp->outPtr = bp->inPtr = bp->buffer; 291138337Sharti bp->left = bp->size; 292138337Sharti *bp->inPtr = 0; 293138337Sharti } 294138337Sharti return (numBytes); 2951590Srgrimes} 296138232Sharti 2971590Srgrimes/*- 2981590Srgrimes *----------------------------------------------------------------------- 2991590Srgrimes * Buf_GetAll -- 3001590Srgrimes * Get all the available data at once. 3011590Srgrimes * 3021590Srgrimes * Results: 3031590Srgrimes * A pointer to the data and the number of bytes available. 3041590Srgrimes * 3051590Srgrimes * Side Effects: 3061590Srgrimes * None. 3071590Srgrimes * 3081590Srgrimes *----------------------------------------------------------------------- 3091590Srgrimes */ 3101590SrgrimesByte * 311138341ShartiBuf_GetAll(Buffer bp, size_t *numBytesPtr) 3121590Srgrimes{ 3131590Srgrimes 314138337Sharti if (numBytesPtr != NULL) 315138337Sharti *numBytesPtr = bp->inPtr - bp->outPtr; 3168874Srgrimes 317138337Sharti return (bp->outPtr); 3181590Srgrimes} 319138232Sharti 3201590Srgrimes/*- 3211590Srgrimes *----------------------------------------------------------------------- 3221590Srgrimes * Buf_Discard -- 3231590Srgrimes * Throw away bytes in a buffer. 3241590Srgrimes * 3251590Srgrimes * Results: 3261590Srgrimes * None. 3271590Srgrimes * 3281590Srgrimes * Side Effects: 3298874Srgrimes * The bytes are discarded. 3301590Srgrimes * 3311590Srgrimes *----------------------------------------------------------------------- 3321590Srgrimes */ 3331590Srgrimesvoid 334138341ShartiBuf_Discard(Buffer bp, size_t numBytes) 3351590Srgrimes{ 3361590Srgrimes 337138341Sharti if ((size_t)(bp->inPtr - bp->outPtr) <= numBytes) { 338138337Sharti bp->inPtr = bp->outPtr = bp->buffer; 339138337Sharti bp->left = bp->size; 340138337Sharti *bp->inPtr = 0; 341138337Sharti } else 342138337Sharti bp->outPtr += numBytes; 3431590Srgrimes} 344138232Sharti 3451590Srgrimes/*- 3461590Srgrimes *----------------------------------------------------------------------- 3471590Srgrimes * Buf_Size -- 3481590Srgrimes * Returns the number of bytes in the given buffer. Doesn't include 3491590Srgrimes * the null-terminating byte. 3501590Srgrimes * 3511590Srgrimes * Results: 3521590Srgrimes * The number of bytes. 3531590Srgrimes * 3541590Srgrimes * Side Effects: 3551590Srgrimes * None. 3561590Srgrimes * 3571590Srgrimes *----------------------------------------------------------------------- 3581590Srgrimes */ 359138341Shartisize_t 360138232ShartiBuf_Size(Buffer buf) 3611590Srgrimes{ 362138264Sharti 363138337Sharti return (buf->inPtr - buf->outPtr); 3641590Srgrimes} 365138232Sharti 3661590Srgrimes/*- 3671590Srgrimes *----------------------------------------------------------------------- 3681590Srgrimes * Buf_Init -- 3691590Srgrimes * Initialize a buffer. If no initial size is given, a reasonable 3701590Srgrimes * default is used. 3711590Srgrimes * 3721590Srgrimes * Results: 3731590Srgrimes * A buffer to be given to other functions in this library. 3741590Srgrimes * 3751590Srgrimes * Side Effects: 3761590Srgrimes * The buffer is created, the space allocated and pointers 3771590Srgrimes * initialized. 3781590Srgrimes * 3791590Srgrimes *----------------------------------------------------------------------- 3801590Srgrimes */ 3811590SrgrimesBuffer 382138341ShartiBuf_Init(size_t size) 3831590Srgrimes{ 384138337Sharti Buffer bp; /* New Buffer */ 3851590Srgrimes 386138337Sharti bp = emalloc(sizeof(*bp)); 3871590Srgrimes 388138337Sharti if (size <= 0) 389138337Sharti size = BUF_DEF_SIZE; 3901590Srgrimes 391138337Sharti bp->left = bp->size = size; 392138337Sharti bp->buffer = emalloc(size); 393138337Sharti bp->inPtr = bp->outPtr = bp->buffer; 394138337Sharti *bp->inPtr = 0; 395138337Sharti 396138337Sharti return (bp); 3971590Srgrimes} 398138232Sharti 3991590Srgrimes/*- 4001590Srgrimes *----------------------------------------------------------------------- 4011590Srgrimes * Buf_Destroy -- 402104696Sjmallett * Destroy a buffer, and optionally free its data, too. 4031590Srgrimes * 4041590Srgrimes * Results: 4051590Srgrimes * None. 4061590Srgrimes * 4071590Srgrimes * Side Effects: 4081590Srgrimes * The buffer is freed. 4091590Srgrimes * 4101590Srgrimes *----------------------------------------------------------------------- 4111590Srgrimes */ 4121590Srgrimesvoid 413138232ShartiBuf_Destroy(Buffer buf, Boolean freeData) 4141590Srgrimes{ 4158874Srgrimes 416138337Sharti if (freeData) 417138337Sharti free(buf->buffer); 418138337Sharti free(buf); 4191590Srgrimes} 420138232Sharti 42118456Ssteve/*- 42218456Ssteve *----------------------------------------------------------------------- 42318456Ssteve * Buf_ReplaceLastByte -- 42418456Ssteve * Replace the last byte in a buffer. 42518456Ssteve * 42618456Ssteve * Results: 42718456Ssteve * None. 42818456Ssteve * 42918456Ssteve * Side Effects: 43018456Ssteve * If the buffer was empty intially, then a new byte will be added. 43118456Ssteve * Otherwise, the last byte is overwritten. 43218456Ssteve * 43318456Ssteve *----------------------------------------------------------------------- 43418456Ssteve */ 43518456Sstevevoid 436138341ShartiBuf_ReplaceLastByte(Buffer buf, Byte byte) 43718456Ssteve{ 438138337Sharti if (buf->inPtr == buf->outPtr) 439138337Sharti Buf_AddByte(buf, byte); 440138337Sharti else 441138337Sharti *(buf->inPtr - 1) = byte; 44218456Ssteve} 443