GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: libexec/tradcpp/array.h Lines: 12 13 92.3 %
Date: 2017-11-13 Branches: 3 6 50.0 %

Line Branch Exec Source
1
/*-
2
 * Copyright (c) 2009 The NetBSD Foundation, Inc.
3
 * All rights reserved.
4
 *
5
 * This code is derived from software contributed to The NetBSD Foundation
6
 * by David A. Holland.
7
 *
8
 * Redistribution and use in source and binary forms, with or without
9
 * modification, are permitted provided that the following conditions
10
 * are met:
11
 * 1. Redistributions of source code must retain the above copyright
12
 *    notice, this list of conditions and the following disclaimer.
13
 * 2. Redistributions in binary form must reproduce the above copyright
14
 *    notice, this list of conditions and the following disclaimer in the
15
 *    documentation and/or other materials provided with the distribution.
16
 *
17
 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
18
 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
19
 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
20
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
21
 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27
 * POSSIBILITY OF SUCH DAMAGE.
28
 */
29
30
#ifndef ARRAY_H
31
#define ARRAY_H
32
33
#include "inlinedefs.h" // XXX
34
#include "utils.h"
35
36
#define ARRAYS_CHECKED
37
38
#ifdef ARRAYS_CHECKED
39
#include <assert.h>
40
#define arrayassert assert
41
#else
42
#define arrayassert(x) ((void)(x))
43
#endif
44
45
#ifndef ARRAYINLINE
46
#define ARRAYINLINE C99INLINE
47
#endif
48
49
////////////////////////////////////////////////////////////
50
// type and base operations
51
52
struct array {
53
	void **v;
54
	unsigned num, max;
55
};
56
57
struct array *array_create(void);
58
void array_destroy(struct array *);
59
void array_init(struct array *);
60
void array_cleanup(struct array *);
61
ARRAYINLINE unsigned array_num(const struct array *);
62
ARRAYINLINE void *array_get(const struct array *, unsigned index_);
63
ARRAYINLINE void array_set(const struct array *, unsigned index_, void *val);
64
void array_setsize(struct array *, unsigned num);
65
ARRAYINLINE void array_add(struct array *, void *val, unsigned *index_ret);
66
void array_insert(struct array *a, unsigned index_);
67
void array_remove(struct array *a, unsigned index_);
68
69
////////////////////////////////////////////////////////////
70
// inlining for base operations
71
72
ARRAYINLINE unsigned
73
array_num(const struct array *a)
74
{
75
53015044
	return a->num;
76
}
77
78
ARRAYINLINE void *
79
array_get(const struct array *a, unsigned index_)
80
{
81
167463328
	arrayassert(index_ < a->num);
82
83731664
	return a->v[index_];
83
}
84
85
ARRAYINLINE void
86
array_set(const struct array *a, unsigned index_, void *val)
87
{
88
23392
	arrayassert(index_ < a->num);
89
11696
	a->v[index_] = val;
90
11696
}
91
92
ARRAYINLINE void
93
array_add(struct array *a, void *val, unsigned *index_ret)
94
{
95
90644
	unsigned index_ = a->num;
96
45322
	array_setsize(a, index_+1);
97
45322
	a->v[index_] = val;
98
45322
	if (index_ret != NULL) {
99
		*index_ret = index_;
100
	}
101
45322
}
102
103
////////////////////////////////////////////////////////////
104
// bits for declaring and defining typed arrays
105
106
/*
107
 * Usage:
108
 *
109
 * DECLARRAY_BYTYPE(foo, bar, INLINE) declares "struct foo", which is
110
 * an array of pointers to "bar", plus the operations on it.
111
 *
112
 * DECLARRAY(foo, INLINE) is equivalent to
113
 * DECLARRAY_BYTYPE(fooarray, struct foo, INLINE).
114
 *
115
 * DEFARRAY_BYTYPE and DEFARRAY are the same as DECLARRAY except that
116
 * they define the operations.
117
 *
118
 * The argument INLINE can be used as follows:
119
 *
120
 * 1. For no inlining:
121
 *    In foo.h:
122
 *           DECLARRAY(foo, );
123
 *    In foo.c:
124
 *           DEFARRAY(foo, );
125
 *
126
 * 2. To be file-static:
127
 *    In foo.c:
128
 *           DECLARRAY(foo, static);
129
 *           DEFARRAY(foo, static);
130
 *
131
 * 3. To inline using C99:
132
 *    In foo.h:
133
 *           DECLARRAY(foo, inline);
134
 *           DEFARRAY(foo, inline);
135
 *
136
 * 4. To inline with old gcc:
137
 *    In foo.h:
138
 *           #ifndef FOO_INLINE
139
 *           #define FOO_INLINE extern inline
140
 *           #endif
141
 *           DECLARRAY(foo, );
142
 *           DEFARRAY(foo, FOO_INLINE);
143
 *    In foo.c:
144
 *           #define FOO_INLINE
145
 *           #include "foo.h"
146
 *
147
 * 5. To inline such that it works both with old gcc and C99:
148
 *    In foo.h:
149
 *           #ifndef FOO_INLINE
150
 *           #define FOO_INLINE extern inline
151
 *           #endif
152
 *           DECLARRAY(foo, FOO_INLINE);
153
 *           DEFARRAY(foo, FOO_INLINE);
154
 *    In foo.c:
155
 *           #define FOO_INLINE
156
 *           #include "foo.h"
157
 *
158
 * The mechanism in case (4) ensures that an externally linkable
159
 * definition exists.
160
 */
161
162
#define DECLARRAY_BYTYPE(ARRAY, T, INLINE) \
163
	struct ARRAY {							\
164
		struct array arr;					\
165
	};								\
166
									\
167
	INLINE struct ARRAY *ARRAY##_create(void);			\
168
	INLINE void ARRAY##_destroy(struct ARRAY *a);			\
169
	INLINE void ARRAY##_init(struct ARRAY *a);			\
170
	INLINE void ARRAY##_cleanup(struct ARRAY *a);			\
171
	INLINE unsigned ARRAY##_num(const struct ARRAY *a);		\
172
	INLINE T *ARRAY##_get(const struct ARRAY *a, unsigned index_);	\
173
	INLINE void ARRAY##_set(struct ARRAY *a, unsigned index_, T *val); \
174
	INLINE void ARRAY##_setsize(struct ARRAY *a, unsigned num);	\
175
	INLINE void ARRAY##_add(struct ARRAY *a, T *val, unsigned *index_ret);\
176
	INLINE void ARRAY##_insert(struct ARRAY *a, unsigned index_);	\
177
	INLINE void ARRAY##_remove(struct ARRAY *a, unsigned index_)
178
179
180
#define DEFARRAY_BYTYPE(ARRAY, T, INLINE) \
181
	INLINE void						\
182
	ARRAY##_init(struct ARRAY *a)				\
183
	{							\
184
		array_init(&a->arr);				\
185
	}							\
186
								\
187
	INLINE void						\
188
	ARRAY##_cleanup(struct ARRAY *a)			\
189
	{							\
190
		array_cleanup(&a->arr);				\
191
	}							\
192
								\
193
	INLINE struct						\
194
	ARRAY *ARRAY##_create(void)				\
195
	{							\
196
		struct ARRAY *a;				\
197
								\
198
		a = domalloc(sizeof(*a));			\
199
		ARRAY##_init(a);				\
200
		return a;					\
201
	}							\
202
								\
203
	INLINE void						\
204
	ARRAY##_destroy(struct ARRAY *a)			\
205
	{							\
206
		ARRAY##_cleanup(a);				\
207
		dofree(a, sizeof(*a));				\
208
	}							\
209
								\
210
	INLINE unsigned						\
211
	ARRAY##_num(const struct ARRAY *a)			\
212
	{							\
213
		return array_num(&a->arr);			\
214
	}							\
215
								\
216
	INLINE T *						\
217
	ARRAY##_get(const struct ARRAY *a, unsigned index_)	\
218
	{				 			\
219
		return (T *)array_get(&a->arr, index_);		\
220
	}							\
221
								\
222
	INLINE void						\
223
	ARRAY##_set(struct ARRAY *a, unsigned index_, T *val)	\
224
	{				 			\
225
		array_set(&a->arr, index_, (void *)val);	\
226
	}							\
227
								\
228
	INLINE void						\
229
	ARRAY##_setsize(struct ARRAY *a, unsigned num)		\
230
	{				 			\
231
		array_setsize(&a->arr, num);			\
232
	}							\
233
								\
234
	INLINE void						\
235
	ARRAY##_add(struct ARRAY *a, T *val, unsigned *ret)	\
236
	{				 			\
237
		array_add(&a->arr, (void *)val, ret);		\
238
	}							\
239
								\
240
	INLINE void						\
241
	ARRAY##_insert(struct ARRAY *a, unsigned index_)	\
242
	{				 			\
243
		array_insert(&a->arr, index_);			\
244
	}							\
245
								\
246
	INLINE void						\
247
	ARRAY##_remove(struct ARRAY *a, unsigned index_)	\
248
	{				 			\
249
		array_remove(&a->arr, index_);			\
250
	}
251
252
#define DECLARRAY(T, INLINE) DECLARRAY_BYTYPE(T##array, struct T, INLINE)
253
#define DEFARRAY(T, INLINE) DEFARRAY_BYTYPE(T##array, struct T, INLINE)
254
255
#define DESTROYALL_ARRAY(T, INLINE) \
256
	void T##array_destroyall(struct T##array *arr);	\
257
							\
258
	INLINE void					\
259
	T##array_destroyall(struct T##array *arr)	\
260
	{						\
261
		unsigned i, num;			\
262
		struct T *t;				\
263
							\
264
		num = T##array_num(arr);		\
265
		for (i=0; i<num; i++) {			\
266
			t = T##array_get(arr, i);	\
267
			T##_destroy(t);			\
268
		}					\
269
		T##array_setsize(arr, 0);		\
270
	}
271
272
273
////////////////////////////////////////////////////////////
274
// basic array types
275
276
DECLARRAY_BYTYPE(stringarray, char, ARRAYINLINE);
277
102340
DEFARRAY_BYTYPE(stringarray, char, ARRAYINLINE);
278
279
#endif /* ARRAY_H */