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