Do not leak command in formats, from Romain Francoise.
[tmux-openbsd.git] / array.h
blobc811bf6dc87d20c7148c27ac5d49ba336cef6d19
1 /* $OpenBSD$ */
3 /*
4 * Copyright (c) 2006 Nicholas Marriott <nicm@users.sourceforge.net>
6 * Permission to use, copy, modify, and distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
15 * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
16 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
19 #ifndef ARRAY_H
20 #define ARRAY_H
22 #define ARRAY_INITIALIZER { NULL, 0, 0 }
24 #define ARRAY_DECL(n, c) \
25 struct n { \
26 c *list; \
27 u_int num; \
28 size_t space; \
31 #define ARRAY_ITEM(a, i) ((a)->list[i])
32 #define ARRAY_ITEMSIZE(a) (sizeof *(a)->list)
33 #define ARRAY_INITIALSPACE(a) (10 * ARRAY_ITEMSIZE(a))
35 #define ARRAY_ENSURE(a, n) do { \
36 if (UINT_MAX - (n) < (a)->num) \
37 fatalx("number too big"); \
38 if (SIZE_MAX / ((a)->num + (n)) < ARRAY_ITEMSIZE(a)) \
39 fatalx("size too big"); \
40 if ((a)->space == 0) { \
41 (a)->space = ARRAY_INITIALSPACE(a); \
42 (a)->list = xrealloc((a)->list, 1, (a)->space); \
43 } \
44 while ((a)->space <= ((a)->num + (n)) * ARRAY_ITEMSIZE(a)) { \
45 (a)->list = xrealloc((a)->list, 2, (a)->space); \
46 (a)->space *= 2; \
47 } \
48 } while (0)
50 #define ARRAY_EMPTY(a) (((void *) (a)) == NULL || (a)->num == 0)
51 #define ARRAY_LENGTH(a) ((a)->num)
52 #define ARRAY_DATA(a) ((a)->list)
54 #define ARRAY_FIRST(a) ARRAY_ITEM(a, 0)
55 #define ARRAY_LAST(a) ARRAY_ITEM(a, (a)->num - 1)
57 #define ARRAY_INIT(a) do { \
58 (a)->num = 0; \
59 (a)->list = NULL; \
60 (a)->space = 0; \
61 } while (0)
62 #define ARRAY_CLEAR(a) do { \
63 (a)->num = 0; \
64 } while (0)
66 #define ARRAY_SET(a, i, s) do { \
67 (a)->list[i] = s; \
68 } while (0)
70 #define ARRAY_ADD(a, s) do { \
71 ARRAY_ENSURE(a, 1); \
72 (a)->list[(a)->num] = s; \
73 (a)->num++; \
74 } while (0)
75 #define ARRAY_INSERT(a, i, s) do { \
76 ARRAY_ENSURE(a, 1); \
77 if ((i) < (a)->num) { \
78 memmove((a)->list + (i) + 1, (a)->list + (i), \
79 ARRAY_ITEMSIZE(a) * ((a)->num - (i))); \
80 } \
81 (a)->list[i] = s; \
82 (a)->num++; \
83 } while (0)
84 #define ARRAY_REMOVE(a, i) do { \
85 if ((i) < (a)->num - 1) { \
86 memmove((a)->list + (i), (a)->list + (i) + 1, \
87 ARRAY_ITEMSIZE(a) * ((a)->num - (i) - 1)); \
88 } \
89 (a)->num--; \
90 if ((a)->num == 0) \
91 ARRAY_FREE(a); \
92 } while (0)
94 #define ARRAY_EXPAND(a, n) do { \
95 ARRAY_ENSURE(a, n); \
96 (a)->num += n; \
97 } while (0)
98 #define ARRAY_TRUNC(a, n) do { \
99 if ((a)->num > n) \
100 (a)->num -= n; \
101 else \
102 ARRAY_FREE(a); \
103 } while (0)
105 #define ARRAY_CONCAT(a, b) do { \
106 ARRAY_ENSURE(a, (b)->num); \
107 memcpy((a)->list + (a)->num, (b)->list, (b)->num * ARRAY_ITEMSIZE(a)); \
108 (a)->num += (b)->num; \
109 } while (0)
111 #define ARRAY_FREE(a) do { \
112 free((a)->list); \
113 ARRAY_INIT(a); \
114 } while (0)
115 #define ARRAY_FREEALL(a) do { \
116 ARRAY_FREE(a); \
117 free(a); \
118 } while (0)
120 #endif