GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: usr.bin/make/buf.c Lines: 18 25 72.0 %
Date: 2017-11-07 Branches: 9 16 56.3 %

Line Branch Exec Source
1
/*	$OpenBSD: buf.c,v 1.27 2015/04/29 00:42:12 millert Exp $	*/
2
/*	$NetBSD: buf.c,v 1.9 1996/12/31 17:53:21 christos Exp $ */
3
4
/*
5
 * Copyright (c) 1999 Marc Espie.
6
 *
7
 * Extensive code changes for the OpenBSD project.
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
/*
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.
47
 * 3. Neither the name of the University nor the names of its contributors
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 --
66
 *	Functions for automatically expanded buffers.
67
 */
68
69
#include <ctype.h>
70
#include <limits.h>
71
#include <stddef.h>
72
#include <stdint.h>
73
#include <stdlib.h>
74
#include <string.h>
75
#include <stdio.h>
76
#include <stdarg.h>
77
#include "config.h"
78
#include "defines.h"
79
#include "buf.h"
80
#include "stats.h"
81
#include "memory.h"
82
83
#ifdef STATS_BUF
84
#define DO_STAT_BUF(bp, nb)					\
85
	STAT_BUFS_EXPANSION++;			\
86
	if ((bp)->endPtr - (bp)->buffer == 1)			\
87
		STAT_WEIRD_INEFFICIENT++;
88
#else
89
#define DO_STAT_BUF(a, b)
90
#endif
91
92
static void
93
fatal_overflow()
94
{
95
	fprintf(stderr, "buffer size overflow\n");
96
	exit(2);
97
}
98
99
/* BufExpand(bp, nb)
100
 *	Expand buffer bp to hold upto nb additional
101
 *	chars.	Makes sure there's room for an extra '\0' char at
102
 *	the end of the buffer to terminate the string.	*/
103
#define BufExpand(bp,nb)				\
104
do {							\
105
	size_t   occupied = (bp)->inPtr - (bp)->buffer;	\
106
	size_t   size = (bp)->endPtr - (bp)->buffer;	\
107
	DO_STAT_BUF(bp, nb);				\
108
							\
109
	do {						\
110
		if (size <= SIZE_MAX/2) {		\
111
			size *= 2 ;			\
112
		} else {				\
113
			fatal_overflow();		\
114
		}					\
115
	} while (size - occupied < (nb)+1+BUF_MARGIN);	\
116
	(bp)->buffer = (bp)->inPtr = (bp)->endPtr = 	\
117
		erealloc((bp)->buffer, size);		\
118
	(bp)->inPtr += occupied;			\
119
	(bp)->endPtr += size;				\
120
} while (0);
121
122
#define BUF_DEF_SIZE	256	/* Default buffer size */
123
#define BUF_MARGIN	256	/* Make sure we are comfortable */
124
125
/* the hard case for Buf_AddChar: buffer must be expanded to accommodate
126
 * one more char.  */
127
void
128
BufOverflow(Buffer bp)
129
{
130

8348718
	BufExpand(bp, 1);
131
514344
}
132
133
134
void
135
Buf_AddChars(Buffer bp, size_t numBytes, const char *bytesPtr)
136
{
137
138
844656072
	if ((size_t)(bp->endPtr - bp->inPtr) < numBytes+1)
139

13339834
		BufExpand(bp, numBytes);
140
141
422328036
	memcpy(bp->inPtr, bytesPtr, numBytes);
142
422328036
	bp->inPtr += numBytes;
143
422328036
}
144
145
void
146
Buf_printf(Buffer bp, const char *fmt, ...)
147
{
148
4410
	va_list va;
149
	int n;
150
2205
	va_start(va, fmt);
151
2205
	n = vsnprintf(bp->inPtr, bp->endPtr - bp->inPtr, fmt, va);
152
2205
	va_end(va);
153
2205
	if (n > bp->endPtr - bp->inPtr) {
154
		va_list vb;
155
		BufExpand(bp, n);
156
		va_start(vb, fmt);
157
		(void)vsnprintf(bp->inPtr, bp->endPtr - bp->inPtr, fmt, vb);
158
		va_end(vb);
159
	}
160
2205
	bp->inPtr += n;
161
2205
}
162
163
void
164
Buf_Init(Buffer bp, size_t size)
165
{
166
#ifdef STATS_BUF
167
	STAT_TOTAL_BUFS++;
168
	if (size == 0)
169
		STAT_DEFAULT_BUFS++;
170
	if (size == 1)
171
		STAT_WEIRD_BUFS++;
172
#endif
173
247302140
	if (size == 0)
174
		size = BUF_DEF_SIZE;
175
123651070
	bp->inPtr = bp->endPtr = bp->buffer = emalloc(size);
176
123651070
	bp->endPtr += size;
177
123651070
}