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