1 /* $OpenPackages$ */
2 /* $OpenBSD: buf.c,v 1.20 2004/04/07 13:11:35 espie Exp $ */
3 /* $NetBSD: buf.c,v 1.9 1996/12/31 17:53:21 christos Exp $ */
4
5 /*
6 * Copyright (c) 1999 Marc Espie.
7 *
8 * Extensive code changes for the OpenBSD project.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE OPENBSD PROJECT AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OPENBSD
23 * PROJECT OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 */
31 /*
32 * Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
33 * Copyright (c) 1988, 1989 by Adam de Boor
34 * Copyright (c) 1989 by Berkeley Softworks
35 * All rights reserved.
36 *
37 * This code is derived from software contributed to Berkeley by
38 * Adam de Boor.
39 *
40 * Redistribution and use in source and binary forms, with or without
41 * modification, are permitted provided that the following conditions
42 * are met:
43 * 1. Redistributions of source code must retain the above copyright
44 * notice, this list of conditions and the following disclaimer.
45 * 2. Redistributions in binary form must reproduce the above copyright
46 * notice, this list of conditions and the following disclaimer in the
47 * documentation and/or other materials provided with the distribution.
48 * 3. Neither the name of the University nor the names of its contributors
49 * may be used to endorse or promote products derived from this software
50 * without specific prior written permission.
51 *
52 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
53 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
54 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
55 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
56 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
57 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
58 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
59 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
60 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
61 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
62 * SUCH DAMAGE.
63 */
64
65 /*-
66 * buf.c --
67 * Functions for automatically expanded buffers.
68 */
69
70 #include <ctype.h>
71 #include <stddef.h>
72 #include <string.h>
73 #include "config.h"
74 #include "defines.h"
75 #include "buf.h"
76 #include "stats.h"
77 #include "memory.h"
78
79 #ifdef STATS_BUF
80 #define DO_STAT_BUF(bp, nb) \
81 STAT_BUFS_EXPANSION++; \
82 if ((bp)->endPtr - (bp)->buffer == 1) \
83 STAT_WEIRD_INEFFICIENT++;
84 #else
85 #define DO_STAT_BUF(a, b)
86 #endif
87
88 /* BufExpand(bp, nb)
89 * Expand buffer bp to hold upto nb additional
90 * chars. Makes sure there's room for an extra '\0' char at
91 * the end of the buffer to terminate the string. */
92 #define BufExpand(bp,nb) \
93 do { \
94 size_t occupied = (bp)->inPtr - (bp)->buffer; \
95 size_t size = (bp)->endPtr - (bp)->buffer; \
96 DO_STAT_BUF(bp, nb); \
97 \
98 do { \
99 size *= 2 ; \
100 } while (size - occupied < (nb)+1+BUF_MARGIN); \
101 (bp)->buffer = (bp)->inPtr = (bp)->endPtr = \
102 erealloc((bp)->buffer, size); \
103 (bp)->inPtr += occupied; \
104 (bp)->endPtr += size; \
105 } while (0);
106
107 #define BUF_DEF_SIZE 256 /* Default buffer size */
108 #define BUF_MARGIN 256 /* Make sure we are comfortable */
109
110 /* the hard case for Buf_AddChar: buffer must be expanded to accommodate
111 * one more char. */
112 void
BufOverflow(Buffer bp)113 BufOverflow(Buffer bp)
114 {
115 BufExpand(bp, 1);
116 }
117
118
119 void
Buf_AddChars(Buffer bp,size_t numBytes,const char * bytesPtr)120 Buf_AddChars(Buffer bp, size_t numBytes, const char *bytesPtr)
121 {
122
123 if ((size_t)(bp->endPtr - bp->inPtr) < numBytes+1)
124 BufExpand(bp, numBytes);
125
126 memcpy(bp->inPtr, bytesPtr, numBytes);
127 bp->inPtr += numBytes;
128 }
129
130
131 void
Buf_Init(Buffer bp,size_t size)132 Buf_Init(Buffer bp, size_t size)
133 {
134 #ifdef STATS_BUF
135 STAT_TOTAL_BUFS++;
136 if (size == 0)
137 STAT_DEFAULT_BUFS++;
138 if (size == 1)
139 STAT_WEIRD_BUFS++;
140 #endif
141 if (size == 0)
142 size = BUF_DEF_SIZE;
143 bp->inPtr = bp->endPtr = bp->buffer = emalloc(size);
144 bp->endPtr += size;
145 }
146
147 void
Buf_KillTrailingSpaces(Buffer bp)148 Buf_KillTrailingSpaces(Buffer bp)
149 {
150 while (bp->inPtr > bp->buffer + 1 && isspace(bp->inPtr[-1])) {
151 if (bp->inPtr[-2] == '\\')
152 break;
153 bp->inPtr--;
154 }
155 }
156