Sync sys/queue.h with FreeBSD:
[dragonfly.git] / usr.bin / make / buf.c
blob9b30f93d28cb75c03fd5e1cfe7db4d1dc1c050f9
1 /*-
2 * Copyright (c) 2005 Max Okumoto
3 * Copyright (c) 1988, 1989, 1990, 1993
4 * The Regents of the University of California. All rights reserved.
5 * Copyright (c) 1988, 1989 by Adam de Boor
6 * Copyright (c) 1989 by Berkeley Softworks
7 * All rights reserved.
9 * This code is derived from software contributed to Berkeley by
10 * Adam de Boor.
12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions
14 * are met:
15 * 1. Redistributions of source code must retain the above copyright
16 * notice, this list of conditions and the following disclaimer.
17 * 2. Redistributions in binary form must reproduce the above copyright
18 * notice, this list of conditions and the following disclaimer in the
19 * documentation and/or other materials provided with the distribution.
20 * 3. All advertising materials mentioning features or use of this software
21 * must display the following acknowledgement:
22 * This product includes software developed by the University of
23 * California, Berkeley and its contributors.
24 * 4. Neither the name of the University nor the names of its contributors
25 * may be used to endorse or promote products derived from this software
26 * without specific prior written permission.
28 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
29 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
30 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
31 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
32 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
33 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
34 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
35 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
36 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
37 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
38 * SUCH DAMAGE.
40 * @(#)buf.c 8.1 (Berkeley) 6/6/93
41 * $FreeBSD: src/usr.bin/make/buf.c,v 1.32 2005/02/07 11:27:47 harti Exp $
42 * $DragonFly: src/usr.bin/make/buf.c,v 1.43 2005/09/24 07:37:38 okumoto Exp $
46 * buf.c
47 * Functions for automatically-expanded buffers.
50 #include <string.h>
51 #include <stdlib.h>
53 #include "buf.h"
54 #include "util.h"
56 /**
57 * Returns the number of bytes in the buffer. Doesn't include the
58 * null-terminating byte.
60 * @return The number of bytes in Buffer object.
62 inline size_t
63 Buf_Size(const Buffer *buf)
65 return (buf->end - buf->buf);
68 /**
69 * Returns a reference to the data contained in the buffer.
71 * @note Adding data to the Buffer object may invalidate the reference.
73 inline char *
74 Buf_Data(const Buffer *bp)
76 return (bp->buf);
79 /**
80 * Expand the buffer to hold the number of additional bytes, plus
81 * space to store a terminating NULL byte.
83 static inline void
84 BufExpand(Buffer *bp, size_t nb)
86 size_t len = Buf_Size(bp);
87 if (bp->size < len + nb + 1) {
88 int size = bp->size + MAX(nb + 1, BUF_ADD_INC);
90 bp->buf = erealloc(bp->buf, size);
91 bp->size = size;
92 bp->end = bp->buf + len;
96 /**
97 * Add a single byte to the buffer.
99 inline void
100 Buf_AddByte(Buffer *bp, char byte)
102 BufExpand(bp, 1);
104 *bp->end = byte;
105 bp->end++;
106 *bp->end = '\0';
110 * Add bytes to the buffer.
112 void
113 Buf_AddBytes(Buffer *bp, size_t len, const char bytes[])
115 BufExpand(bp, len);
117 memcpy(bp->end, bytes, len);
118 bp->end += len;
119 *bp->end = '\0';
123 * Get the contents of a buffer and destroy the buffer. If the buffer
124 * is NULL, return NULL.
126 * Returns:
127 * the pointer to the data.
129 char *
130 Buf_Peel(Buffer *bp)
132 char *ret;
134 if (bp == NULL)
135 return (NULL);
136 ret = bp->buf;
137 free(bp);
138 return (ret);
142 * Initialize a buffer. If no initial size is given, a reasonable
143 * default is used.
145 * @return A buffer object to be given to other functions in this library.
147 * Side Effects:
148 * Space is allocated for the Buffer object and a internal buffer.
150 Buffer *
151 Buf_Init(size_t size)
153 Buffer *bp; /* New Buffer */
155 if (size <= 0)
156 size = BUF_DEF_SIZE;
158 bp = emalloc(sizeof(*bp));
159 bp->size = size;
160 bp->buf = emalloc(size);
161 bp->end = bp->buf;
162 *bp->end = '\0';
164 return (bp);
168 * Destroy a buffer, and optionally free its data, too.
170 * Side Effects:
171 * Space for the Buffer object and possibly the internal buffer
172 * is de-allocated.
174 void
175 Buf_Destroy(Buffer *buf, bool freeData)
177 if (freeData)
178 free(buf->buf);
179 free(buf);
183 * Replace the last byte in a buffer. If the buffer was empty
184 * intially, then a new byte will be added.
186 void
187 Buf_ReplaceLastByte(Buffer *bp, char byte)
189 if (bp->end == bp->buf) {
190 Buf_AddByte(bp, byte);
191 } else {
192 *(bp->end - 1) = byte;
197 * Append characters in str to Buffer object
199 void
200 Buf_Append(Buffer *bp, const char str[])
202 Buf_AddBytes(bp, strlen(str), str);
206 * Append characters in buf to Buffer object
208 void
209 Buf_AppendBuf(Buffer *bp, const Buffer *buf)
211 Buf_AddBytes(bp, Buf_Size(buf), buf->buf);
215 * Append characters between str and end to Buffer object.
217 void
218 Buf_AppendRange(Buffer *bp, const char str[], const char *end)
220 Buf_AddBytes(bp, end - str, str);
224 * Convert newlines in buffer to spaces. The trailing newline is
225 * removed.
227 void
228 Buf_StripNewlines(Buffer *bp)
230 char *ptr = bp->end;
233 * If there is anything in the buffer, remove the last
234 * newline character.
236 if (ptr != bp->buf) {
237 if (*(ptr - 1) == '\n') {
238 /* shorten buffer */
239 *(ptr - 1) = '\0';
240 --bp->end;
242 --ptr;
245 /* Convert newline characters to a space characters. */
246 while (ptr != bp->buf) {
247 if (*ptr == '\n') {
248 *ptr = ' ';
250 --ptr;
255 * Clear the contents of the buffer.
257 void
258 Buf_Clear(Buffer *bp)
260 bp->end = bp->buf;
261 *bp->end = '\0';