buf.c revision 104696
1123281Simp/* 2123281Simp * Copyright (c) 1988, 1989, 1990, 1993 3123281Simp * The Regents of the University of California. All rights reserved. 4123281Simp * Copyright (c) 1988, 1989 by Adam de Boor 5123943Sru * Copyright (c) 1989 by Berkeley Softworks 6123281Simp * All rights reserved. 7123281Simp * 8123281Simp * This code is derived from software contributed to Berkeley by 9123281Simp * Adam de Boor. 10123281Simp * 11123281Simp * Redistribution and use in source and binary forms, with or without 12123281Simp * modification, are permitted provided that the following conditions 13123281Simp * are met: 14123281Simp * 1. Redistributions of source code must retain the above copyright 15123281Simp * notice, this list of conditions and the following disclaimer. 16123281Simp * 2. Redistributions in binary form must reproduce the above copyright 17123281Simp * notice, this list of conditions and the following disclaimer in the 18123281Simp * documentation and/or other materials provided with the distribution. 19123281Simp * 3. All advertising materials mentioning features or use of this software 20123281Simp * must display the following acknowledgement: 21123281Simp * This product includes software developed by the University of 22123281Simp * California, Berkeley and its contributors. 23123281Simp * 4. Neither the name of the University nor the names of its contributors 24123281Simp * may be used to endorse or promote products derived from this software 25123281Simp * without specific prior written permission. 26123281Simp * 27123281Simp * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 28123281Simp * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 29123281Simp * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 30123281Simp * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 31123281Simp * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 32123281Simp * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 33123281Simp * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 34123281Simp * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 35123281Simp * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 36123281Simp * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 37123281Simp * SUCH DAMAGE. 38123281Simp * 39123281Simp * @(#)buf.c 8.1 (Berkeley) 6/6/93 40123281Simp */ 41123281Simp 42123281Simp#include <sys/cdefs.h> 43123281Simp__FBSDID("$FreeBSD: head/usr.bin/make/buf.c 104696 2002-10-09 03:42:10Z jmallett $"); 44123281Simp 45123281Simp/*- 46123281Simp * buf.c -- 47123281Simp * Functions for automatically-expanded buffers. 48123281Simp */ 49123281Simp 50123281Simp#include "sprite.h" 51123281Simp#include "make.h" 52123281Simp#include "buf.h" 53123281Simp 54123281Simp#ifndef max 55123281Simp#define max(a,b) ((a) > (b) ? (a) : (b)) 56123281Simp#endif 57123281Simp 58123281Simp/* 59123281Simp * BufExpand -- 60123281Simp * Expand the given buffer to hold the given number of additional 61123281Simp * bytes. 62123281Simp * Makes sure there's room for an extra NULL byte at the end of the 63123281Simp * buffer in case it holds a string. 64123281Simp */ 65123281Simp#define BufExpand(bp,nb) \ 66123281Simp if (bp->left < (nb)+1) {\ 67123281Simp int newSize = (bp)->size + max((nb)+1,BUF_ADD_INC); \ 68123281Simp Byte *newBuf = (Byte *) erealloc((bp)->buffer, newSize); \ 69123281Simp \ 70123281Simp (bp)->inPtr = newBuf + ((bp)->inPtr - (bp)->buffer); \ 71123281Simp (bp)->outPtr = newBuf + ((bp)->outPtr - (bp)->buffer);\ 72123281Simp (bp)->buffer = newBuf;\ 73123281Simp (bp)->size = newSize;\ 74123281Simp (bp)->left = newSize - ((bp)->inPtr - (bp)->buffer);\ 75123281Simp } 76123281Simp 77123281Simp#define BUF_DEF_SIZE 256 /* Default buffer size */ 78123281Simp#define BUF_ADD_INC 256 /* Expansion increment when Adding */ 79123281Simp#define BUF_UNGET_INC 16 /* Expansion increment when Ungetting */ 80123281Simp 81123281Simp/*- 82123281Simp *----------------------------------------------------------------------- 83123281Simp * Buf_OvAddByte -- 84123281Simp * Add a single byte to the buffer. left is zero or negative. 85123281Simp * 86123281Simp * Results: 87123281Simp * None. 88123281Simp * 89123281Simp * Side Effects: 90123281Simp * The buffer may be expanded. 91123281Simp * 92123281Simp *----------------------------------------------------------------------- 93123281Simp */ 94123281Simpvoid 95123281SimpBuf_OvAddByte (Buffer bp, int byte) 96123281Simp{ 97123281Simp bp->left = 0; 98123281Simp BufExpand (bp, 1); 99123281Simp 100123281Simp *bp->inPtr++ = byte; 101123281Simp bp->left--; 102123281Simp 103123281Simp /* 104123281Simp * Null-terminate 105123281Simp */ 106123281Simp *bp->inPtr = 0; 107123281Simp} 108123281Simp 109123281Simp/*- 110123281Simp *----------------------------------------------------------------------- 111123281Simp * Buf_AddBytes -- 112123281Simp * Add a number of bytes to the buffer. 113123281Simp * 114123281Simp * Results: 115123281Simp * None. 116123281Simp * 117123281Simp * Side Effects: 118123281Simp * Guess what? 119123281Simp * 120123281Simp *----------------------------------------------------------------------- 121123281Simp */ 122123281Simpvoid 123123281SimpBuf_AddBytes (Buffer bp, int numBytes, const Byte *bytesPtr) 124123281Simp{ 125123281Simp 126123281Simp BufExpand (bp, numBytes); 127123281Simp 128123281Simp memcpy (bp->inPtr, bytesPtr, numBytes); 129123281Simp bp->inPtr += numBytes; 130123281Simp bp->left -= numBytes; 131123281Simp 132123281Simp /* 133123281Simp * Null-terminate 134123281Simp */ 135123281Simp *bp->inPtr = 0; 136123281Simp} 137123281Simp 138123281Simp/*- 139123281Simp *----------------------------------------------------------------------- 140123281Simp * Buf_UngetByte -- 141123281Simp * Place the byte back at the beginning of the buffer. 142123281Simp * 143123281Simp * Results: 144123281Simp * SUCCESS if the byte was added ok. FAILURE if not. 145123281Simp * 146123281Simp * Side Effects: 147123281Simp * The byte is stuffed in the buffer and outPtr is decremented. 148123281Simp * 149123281Simp *----------------------------------------------------------------------- 150123281Simp */ 151123281Simpvoid 152123281SimpBuf_UngetByte (Buffer bp, int byte) 153123281Simp{ 154123281Simp 155123281Simp if (bp->outPtr != bp->buffer) { 156123281Simp bp->outPtr--; 157123281Simp *bp->outPtr = byte; 158123281Simp } else if (bp->outPtr == bp->inPtr) { 159123281Simp *bp->inPtr = byte; 160123281Simp bp->inPtr++; 161123281Simp bp->left--; 162123281Simp *bp->inPtr = 0; 163123281Simp } else { 164123281Simp /* 165123281Simp * Yech. have to expand the buffer to stuff this thing in. 166123281Simp * We use a different expansion constant because people don't 167123281Simp * usually push back many bytes when they're doing it a byte at 168123281Simp * a time... 169123281Simp */ 170123281Simp int numBytes = bp->inPtr - bp->outPtr; 171123281Simp Byte *newBuf; 172123281Simp 173123281Simp newBuf = (Byte *)emalloc(bp->size + BUF_UNGET_INC); 174123281Simp memcpy ((char *)(newBuf+BUF_UNGET_INC), (char *)bp->outPtr, numBytes+1); 175123281Simp bp->outPtr = newBuf + BUF_UNGET_INC; 176123281Simp bp->inPtr = bp->outPtr + numBytes; 177123281Simp free ((char *)bp->buffer); 178123281Simp bp->buffer = newBuf; 179123281Simp bp->size += BUF_UNGET_INC; 180123281Simp bp->left = bp->size - (bp->inPtr - bp->buffer); 181123281Simp bp->outPtr -= 1; 182123281Simp *bp->outPtr = byte; 183123281Simp } 184123281Simp} 185123281Simp 186123281Simp/*- 187123281Simp *----------------------------------------------------------------------- 188123281Simp * Buf_UngetBytes -- 189123281Simp * Push back a series of bytes at the beginning of the buffer. 190123281Simp * 191123281Simp * Results: 192123281Simp * None. 193123281Simp * 194123281Simp * Side Effects: 195123281Simp * outPtr is decremented and the bytes copied into the buffer. 196123281Simp * 197123281Simp *----------------------------------------------------------------------- 198123281Simp */ 199123281Simpvoid 200123281SimpBuf_UngetBytes (Buffer bp, int numBytes, Byte *bytesPtr) 201123281Simp{ 202123281Simp 203123281Simp if (bp->outPtr - bp->buffer >= numBytes) { 204123281Simp bp->outPtr -= numBytes; 205123281Simp memcpy (bp->outPtr, bytesPtr, numBytes); 206123281Simp } else if (bp->outPtr == bp->inPtr) { 207123281Simp Buf_AddBytes (bp, numBytes, bytesPtr); 208123281Simp } else { 209123281Simp int curNumBytes = bp->inPtr - bp->outPtr; 210123281Simp Byte *newBuf; 211123281Simp int newBytes = max(numBytes,BUF_UNGET_INC); 212123281Simp 213123281Simp newBuf = (Byte *)emalloc (bp->size + newBytes); 214123281Simp memcpy((char *)(newBuf+newBytes), (char *)bp->outPtr, curNumBytes+1); 215123281Simp bp->outPtr = newBuf + newBytes; 216123281Simp bp->inPtr = bp->outPtr + curNumBytes; 217123281Simp free ((char *)bp->buffer); 218123281Simp bp->buffer = newBuf; 219123281Simp bp->size += newBytes; 220123281Simp bp->left = bp->size - (bp->inPtr - bp->buffer); 221123281Simp bp->outPtr -= numBytes; 222123281Simp memcpy ((char *)bp->outPtr, (char *)bytesPtr, numBytes); 223123281Simp } 224123281Simp} 225123281Simp 226123281Simp/*- 227123281Simp *----------------------------------------------------------------------- 228123281Simp * Buf_GetByte -- 229123281Simp * Return the next byte from the buffer. Actually returns an integer. 230123281Simp * 231123281Simp * Results: 232123281Simp * Returns BUF_ERROR if there's no byte in the buffer, or the byte 233123281Simp * itself if there is one. 234123281Simp * 235123281Simp * Side Effects: 236123281Simp * outPtr is incremented and both outPtr and inPtr will be reset if 237123281Simp * the buffer is emptied. 238123281Simp * 239123281Simp *----------------------------------------------------------------------- 240123281Simp */ 241123281Simpint 242123281SimpBuf_GetByte (Buffer bp) 243123281Simp{ 244123281Simp int res; 245123281Simp 246123281Simp if (bp->inPtr == bp->outPtr) { 247123281Simp return (BUF_ERROR); 248123281Simp } else { 249123281Simp res = (int) *bp->outPtr; 250123281Simp bp->outPtr += 1; 251123281Simp if (bp->outPtr == bp->inPtr) { 252123281Simp bp->outPtr = bp->inPtr = bp->buffer; 253123281Simp bp->left = bp->size; 254123281Simp *bp->inPtr = 0; 255123281Simp } 256123281Simp return (res); 257123281Simp } 258123281Simp} 259123281Simp 260123281Simp/*- 261123281Simp *----------------------------------------------------------------------- 262123281Simp * Buf_GetBytes -- 263123281Simp * Extract a number of bytes from the buffer. 264123281Simp * 265123281Simp * Results: 266123281Simp * The number of bytes gotten. 267123281Simp * 268123281Simp * Side Effects: 269123281Simp * The passed array is overwritten. 270123281Simp * 271123281Simp *----------------------------------------------------------------------- 272123281Simp */ 273123281Simpint 274123281SimpBuf_GetBytes (Buffer bp, int numBytes, Byte *bytesPtr) 275123281Simp{ 276123281Simp 277123281Simp if (bp->inPtr - bp->outPtr < numBytes) { 278123281Simp numBytes = bp->inPtr - bp->outPtr; 279123281Simp } 280123281Simp memcpy (bytesPtr, bp->outPtr, numBytes); 281123281Simp bp->outPtr += numBytes; 282123281Simp 283123281Simp if (bp->outPtr == bp->inPtr) { 284123281Simp bp->outPtr = bp->inPtr = bp->buffer; 285123281Simp bp->left = bp->size; 286123281Simp *bp->inPtr = 0; 287123281Simp } 288123281Simp return (numBytes); 289123281Simp} 290123281Simp 291123281Simp/*- 292123281Simp *----------------------------------------------------------------------- 293123281Simp * Buf_GetAll -- 294123281Simp * Get all the available data at once. 295123281Simp * 296123281Simp * Results: 297123281Simp * A pointer to the data and the number of bytes available. 298123281Simp * 299123281Simp * Side Effects: 300123281Simp * None. 301123281Simp * 302123281Simp *----------------------------------------------------------------------- 303123281Simp */ 304123281SimpByte * 305123281SimpBuf_GetAll (Buffer bp, int *numBytesPtr) 306123281Simp{ 307123281Simp 308123281Simp if (numBytesPtr != (int *)NULL) { 309123281Simp *numBytesPtr = bp->inPtr - bp->outPtr; 310123281Simp } 311123281Simp 312123281Simp return (bp->outPtr); 313123281Simp} 314123281Simp 315123281Simp/*- 316123281Simp *----------------------------------------------------------------------- 317123281Simp * Buf_Discard -- 318123281Simp * Throw away bytes in a buffer. 319123281Simp * 320123281Simp * Results: 321123281Simp * None. 322123281Simp * 323123281Simp * Side Effects: 324123281Simp * The bytes are discarded. 325123281Simp * 326123281Simp *----------------------------------------------------------------------- 327123281Simp */ 328123281Simpvoid 329123281SimpBuf_Discard (Buffer bp, int numBytes) 330123281Simp{ 331123281Simp 332123281Simp if (bp->inPtr - bp->outPtr <= numBytes) { 333123281Simp bp->inPtr = bp->outPtr = bp->buffer; 334123281Simp bp->left = bp->size; 335123281Simp *bp->inPtr = 0; 336123281Simp } else { 337123281Simp bp->outPtr += numBytes; 338123281Simp } 339123281Simp} 340123281Simp 341123281Simp/*- 342123281Simp *----------------------------------------------------------------------- 343123281Simp * Buf_Size -- 344123281Simp * Returns the number of bytes in the given buffer. Doesn't include 345123281Simp * the null-terminating byte. 346123281Simp * 347123281Simp * Results: 348123281Simp * The number of bytes. 349123281Simp * 350123281Simp * Side Effects: 351123281Simp * None. 352123281Simp * 353123281Simp *----------------------------------------------------------------------- 354123281Simp */ 355123281Simpint 356123281SimpBuf_Size (Buffer buf) 357123281Simp{ 358123281Simp return (buf->inPtr - buf->outPtr); 359123281Simp} 360123281Simp 361123281Simp/*- 362123281Simp *----------------------------------------------------------------------- 363123281Simp * Buf_Init -- 364123281Simp * Initialize a buffer. If no initial size is given, a reasonable 365123281Simp * default is used. 366123281Simp * 367123281Simp * Results: 368123281Simp * A buffer to be given to other functions in this library. 369123281Simp * 370123281Simp * Side Effects: 371123281Simp * The buffer is created, the space allocated and pointers 372123281Simp * initialized. 373123281Simp * 374123281Simp *----------------------------------------------------------------------- 375123281Simp */ 376123281SimpBuffer 377123281SimpBuf_Init (int size) 378123281Simp{ 379123281Simp Buffer bp; /* New Buffer */ 380123281Simp 381123281Simp bp = (Buffer)emalloc(sizeof(*bp)); 382123281Simp 383123281Simp if (size <= 0) { 384123281Simp size = BUF_DEF_SIZE; 385123281Simp } 386123281Simp bp->left = bp->size = size; 387123281Simp bp->buffer = (Byte *)emalloc(size); 388123281Simp bp->inPtr = bp->outPtr = bp->buffer; 389123281Simp *bp->inPtr = 0; 390123281Simp 391123281Simp return (bp); 392123281Simp} 393123281Simp 394123281Simp/*- 395123281Simp *----------------------------------------------------------------------- 396123281Simp * Buf_Destroy -- 397123281Simp * Destroy a buffer, and optionally free its data, too. 398123281Simp * 399123281Simp * Results: 400123281Simp * None. 401123281Simp * 402123281Simp * Side Effects: 403123281Simp * The buffer is freed. 404123281Simp * 405123281Simp *----------------------------------------------------------------------- 406123281Simp */ 407123281Simpvoid 408123281SimpBuf_Destroy (Buffer buf, Boolean freeData) 409123281Simp{ 410123281Simp 411123281Simp if (freeData) { 412123281Simp free ((char *)buf->buffer); 413123281Simp } 414123281Simp free ((char *)buf); 415123281Simp} 416123281Simp 417123281Simp/*- 418123281Simp *----------------------------------------------------------------------- 419123281Simp * Buf_ReplaceLastByte -- 420123281Simp * Replace the last byte in a buffer. 421123281Simp * 422123281Simp * Results: 423123281Simp * None. 424123281Simp * 425123281Simp * Side Effects: 426123281Simp * If the buffer was empty intially, then a new byte will be added. 427123281Simp * Otherwise, the last byte is overwritten. 428123281Simp * 429123281Simp *----------------------------------------------------------------------- 430123281Simp */ 431123281Simpvoid 432123281SimpBuf_ReplaceLastByte (Buffer buf, int byte) 433123281Simp{ 434123281Simp if (buf->inPtr == buf->outPtr) 435123281Simp Buf_AddByte(buf, byte); 436123281Simp else 437123281Simp *(buf->inPtr - 1) = byte; 438123281Simp} 439123281Simp