Annotation of src/usr.bin/make/buf.c, Revision 1.29
1.29 ! espie 1: /* $OpenBSD: buf.c,v 1.28 2019/12/21 15:26:47 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.28 espie 69: #include <assert.h>
1.16 espie 70: #include <ctype.h>
1.26 espie 71: #include <limits.h>
1.16 espie 72: #include <stddef.h>
1.27 millert 73: #include <stdint.h>
1.26 espie 74: #include <stdlib.h>
1.17 espie 75: #include <string.h>
1.24 espie 76: #include <stdio.h>
77: #include <stdarg.h>
1.16 espie 78: #include "config.h"
79: #include "defines.h"
80: #include "buf.h"
81: #include "stats.h"
82: #include "memory.h"
1.15 espie 83:
84: #ifdef STATS_BUF
85: #define DO_STAT_BUF(bp, nb) \
86: STAT_BUFS_EXPANSION++; \
87: if ((bp)->endPtr - (bp)->buffer == 1) \
88: STAT_WEIRD_INEFFICIENT++;
89: #else
90: #define DO_STAT_BUF(a, b)
91: #endif
92:
1.26 espie 93: static void
94: fatal_overflow()
95: {
96: fprintf(stderr, "buffer size overflow\n");
97: exit(2);
98: }
99:
1.28 espie 100: #define BUF_DEF_SIZE 256U /* Default buffer size */
101: #define BUF_MARGIN 256U /* Make sure we are comfortable */
102:
1.16 espie 103: /* BufExpand(bp, nb)
1.28 espie 104: * Expand buffer bp to hold up to nb additional
105: * chars. Makes sure there's always room for an extra '\0' char
106: * at the end of the buffer for Buf_Retrieve. */
1.1 deraadt 107: void
1.28 espie 108: BufExpand(Buffer bp, size_t nb)
1.1 deraadt 109: {
1.28 espie 110: size_t occupied = bp->inPtr - bp->buffer;
111: size_t size = bp->endPtr - bp->buffer;
112: DO_STAT_BUF(bp, nb);
113:
114: do {
115: if (size <= SIZE_MAX/2) {
116: size *= 2 ;
117: } else {
118: fatal_overflow();
119: }
120: assert(size >= occupied);
121: } while (size - occupied < nb+1+BUF_MARGIN);
122: bp->buffer = erealloc(bp->buffer, size);
123: bp->inPtr = bp->buffer +occupied;
124: bp->endPtr = bp->buffer + size;
1.1 deraadt 125: }
1.11 espie 126:
1.1 deraadt 127: void
1.20 espie 128: Buf_AddChars(Buffer bp, size_t numBytes, const char *bytesPtr)
1.1 deraadt 129: {
1.28 espie 130: assert(bp->endPtr >= bp->inPtr);
1.21 espie 131: if ((size_t)(bp->endPtr - bp->inPtr) < numBytes+1)
132: BufExpand(bp, numBytes);
1.1 deraadt 133:
1.21 espie 134: memcpy(bp->inPtr, bytesPtr, numBytes);
135: bp->inPtr += numBytes;
1.1 deraadt 136: }
137:
1.24 espie 138: void
139: Buf_printf(Buffer bp, const char *fmt, ...)
140: {
141: va_list va;
142: int n;
143: va_start(va, fmt);
144: n = vsnprintf(bp->inPtr, bp->endPtr - bp->inPtr, fmt, va);
145: va_end(va);
1.28 espie 146: if (n+1 > bp->endPtr - bp->inPtr) {
1.24 espie 147: va_list vb;
148: BufExpand(bp, n);
149: va_start(vb, fmt);
150: (void)vsnprintf(bp->inPtr, bp->endPtr - bp->inPtr, fmt, vb);
151: va_end(vb);
152: }
153: bp->inPtr += n;
1.29 ! espie 154: }
! 155:
! 156: void
! 157: Buf_Reinit(Buffer bp, size_t size)
! 158: {
! 159: if (bp->buffer == NULL)
! 160: Buf_Init(bp, size);
! 161: else
! 162: Buf_Reset(bp);
1.24 espie 163: }
1.15 espie 164:
1.12 espie 165: void
1.20 espie 166: Buf_Init(Buffer bp, size_t size)
1.1 deraadt 167: {
1.15 espie 168: #ifdef STATS_BUF
1.21 espie 169: STAT_TOTAL_BUFS++;
170: if (size == 0)
171: STAT_DEFAULT_BUFS++;
172: if (size == 1)
173: STAT_WEIRD_BUFS++;
1.15 espie 174: #endif
1.21 espie 175: if (size == 0)
176: size = BUF_DEF_SIZE;
177: bp->inPtr = bp->endPtr = bp->buffer = emalloc(size);
178: bp->endPtr += size;
1.1 deraadt 179: }