sbin/hammer: Add a TODO comment for hammer recover
[dragonfly.git] / contrib / nvi2 / common / mem.h
blobb2b44b62ec8e66e892c88a61377984d1cd7aabe1
1 /*-
2 * Copyright (c) 1993, 1994
3 * The Regents of the University of California. All rights reserved.
4 * Copyright (c) 1993, 1994, 1995, 1996
5 * Keith Bostic. All rights reserved.
7 * See the LICENSE file for redistribution information.
9 * $Id: mem.h,v 10.17 2012/10/07 00:40:29 zy Exp $
12 #ifdef DEBUG
13 #define CHECK_TYPE(type, var) \
14 type L__lp __attribute__((unused)) = var;
15 #else
16 #define CHECK_TYPE(type, var)
17 #endif
19 /* Increase the size of a malloc'd buffer. Two versions, one that
20 * returns, one that jumps to an error label.
22 #define BINC_GOTO(sp, type, lp, llen, nlen) { \
23 CHECK_TYPE(type *, lp) \
24 void *L__bincp; \
25 if ((nlen) > llen) { \
26 if ((L__bincp = binc(sp, lp, &(llen), nlen)) == NULL) \
27 goto alloc_err; \
28 /* \
29 * !!! \
30 * Possible pointer conversion. \
31 */ \
32 lp = L__bincp; \
33 } \
35 #define BINC_GOTOC(sp, lp, llen, nlen) \
36 BINC_GOTO(sp, char, lp, llen, nlen)
37 #define BINC_GOTOW(sp, lp, llen, nlen) \
38 BINC_GOTO(sp, CHAR_T, lp, llen, (nlen) * sizeof(CHAR_T))
39 #define BINC_RET(sp, type, lp, llen, nlen) { \
40 CHECK_TYPE(type *, lp) \
41 void *L__bincp; \
42 if ((nlen) > llen) { \
43 if ((L__bincp = binc(sp, lp, &(llen), nlen)) == NULL) \
44 return (1); \
45 /* \
46 * !!! \
47 * Possible pointer conversion. \
48 */ \
49 lp = L__bincp; \
50 } \
52 #define BINC_RETC(sp, lp, llen, nlen) \
53 BINC_RET(sp, char, lp, llen, nlen)
54 #define BINC_RETW(sp, lp, llen, nlen) \
55 BINC_RET(sp, CHAR_T, lp, llen, (nlen) * sizeof(CHAR_T))
58 * Get some temporary space, preferably from the global temporary buffer,
59 * from a malloc'd buffer otherwise. Two versions, one that returns, one
60 * that jumps to an error label.
62 #define GET_SPACE_GOTO(sp, type, bp, blen, nlen) { \
63 CHECK_TYPE(type *, bp) \
64 GS *L__gp = (sp) == NULL ? NULL : (sp)->gp; \
65 if (L__gp == NULL || F_ISSET(L__gp, G_TMP_INUSE)) { \
66 bp = NULL; \
67 blen = 0; \
68 BINC_GOTO(sp, type, bp, blen, nlen); \
69 } else { \
70 BINC_GOTOC(sp, L__gp->tmp_bp, L__gp->tmp_blen, nlen); \
71 bp = (type *) L__gp->tmp_bp; \
72 blen = L__gp->tmp_blen; \
73 F_SET(L__gp, G_TMP_INUSE); \
74 } \
76 #define GET_SPACE_GOTOC(sp, bp, blen, nlen) \
77 GET_SPACE_GOTO(sp, char, bp, blen, nlen)
78 #define GET_SPACE_GOTOW(sp, bp, blen, nlen) \
79 GET_SPACE_GOTO(sp, CHAR_T, bp, blen, (nlen) * sizeof(CHAR_T))
80 #define GET_SPACE_RET(sp, type, bp, blen, nlen) { \
81 CHECK_TYPE(type *, bp) \
82 GS *L__gp = (sp) == NULL ? NULL : (sp)->gp; \
83 if (L__gp == NULL || F_ISSET(L__gp, G_TMP_INUSE)) { \
84 bp = NULL; \
85 blen = 0; \
86 BINC_RET(sp, type, bp, blen, nlen); \
87 } else { \
88 BINC_RETC(sp, L__gp->tmp_bp, L__gp->tmp_blen, nlen); \
89 bp = (type *) L__gp->tmp_bp; \
90 blen = L__gp->tmp_blen; \
91 F_SET(L__gp, G_TMP_INUSE); \
92 } \
94 #define GET_SPACE_RETC(sp, bp, blen, nlen) \
95 GET_SPACE_RET(sp, char, bp, blen, nlen)
96 #define GET_SPACE_RETW(sp, bp, blen, nlen) \
97 GET_SPACE_RET(sp, CHAR_T, bp, blen, (nlen) * sizeof(CHAR_T))
100 * Add space to a GET_SPACE returned buffer. Two versions, one that
101 * returns, one that jumps to an error label.
103 #define ADD_SPACE_GOTO(sp, type, bp, blen, nlen) { \
104 CHECK_TYPE(type *, bp) \
105 GS *L__gp = (sp) == NULL ? NULL : (sp)->gp; \
106 if (L__gp == NULL || bp == (type *)L__gp->tmp_bp) { \
107 F_CLR(L__gp, G_TMP_INUSE); \
108 BINC_GOTOC(sp, L__gp->tmp_bp, L__gp->tmp_blen, nlen); \
109 bp = (type *) L__gp->tmp_bp; \
110 blen = L__gp->tmp_blen; \
111 F_SET(L__gp, G_TMP_INUSE); \
112 } else \
113 BINC_GOTO(sp, type, bp, blen, nlen); \
115 #define ADD_SPACE_GOTOC(sp, bp, blen, nlen) \
116 ADD_SPACE_GOTO(sp, char, bp, blen, nlen)
117 #define ADD_SPACE_GOTOW(sp, bp, blen, nlen) \
118 ADD_SPACE_GOTO(sp, CHAR_T, bp, blen, (nlen) * sizeof(CHAR_T))
119 #define ADD_SPACE_RET(sp, type, bp, blen, nlen) { \
120 CHECK_TYPE(type *, bp) \
121 GS *L__gp = (sp) == NULL ? NULL : (sp)->gp; \
122 if (L__gp == NULL || bp == (type *)L__gp->tmp_bp) { \
123 F_CLR(L__gp, G_TMP_INUSE); \
124 BINC_RETC(sp, L__gp->tmp_bp, L__gp->tmp_blen, nlen); \
125 bp = (type *) L__gp->tmp_bp; \
126 blen = L__gp->tmp_blen; \
127 F_SET(L__gp, G_TMP_INUSE); \
128 } else \
129 BINC_RET(sp, type, bp, blen, nlen); \
131 #define ADD_SPACE_RETC(sp, bp, blen, nlen) \
132 ADD_SPACE_RET(sp, char, bp, blen, nlen)
133 #define ADD_SPACE_RETW(sp, bp, blen, nlen) \
134 ADD_SPACE_RET(sp, CHAR_T, bp, blen, (nlen) * sizeof(CHAR_T))
136 /* Free a GET_SPACE returned buffer. */
137 #define FREE_SPACE(sp, bp, blen) { \
138 GS *L__gp = (sp) == NULL ? NULL : (sp)->gp; \
139 if (L__gp != NULL && bp == L__gp->tmp_bp) \
140 F_CLR(L__gp, G_TMP_INUSE); \
141 else \
142 free(bp); \
144 #define FREE_SPACEW(sp, bp, blen) { \
145 CHECK_TYPE(CHAR_T *, bp) \
146 FREE_SPACE(sp, (char *)bp, blen); \
150 * Malloc a buffer, casting the return pointer. Various versions.
152 * !!!
153 * The cast should be unnecessary, malloc(3) and friends return void *'s,
154 * which is all we need. However, some systems that nvi needs to run on
155 * don't do it right yet, resulting in the compiler printing out roughly
156 * a million warnings. After awhile, it seemed easier to put the casts
157 * in instead of explaining it all the time.
159 #define CALLOC(sp, p, cast, nmemb, size) { \
160 if ((p = (cast)calloc(nmemb, size)) == NULL) \
161 msgq(sp, M_SYSERR, NULL); \
163 #define CALLOC_GOTO(sp, p, cast, nmemb, size) { \
164 if ((p = (cast)calloc(nmemb, size)) == NULL) \
165 goto alloc_err; \
167 #define CALLOC_NOMSG(sp, p, cast, nmemb, size) { \
168 p = (cast)calloc(nmemb, size); \
170 #define CALLOC_RET(sp, p, cast, nmemb, size) { \
171 if ((p = (cast)calloc(nmemb, size)) == NULL) { \
172 msgq(sp, M_SYSERR, NULL); \
173 return (1); \
177 #define MALLOC(sp, p, cast, size) { \
178 if ((p = (cast)malloc(size)) == NULL) \
179 msgq(sp, M_SYSERR, NULL); \
181 #define MALLOC_GOTO(sp, p, cast, size) { \
182 if ((p = (cast)malloc(size)) == NULL) \
183 goto alloc_err; \
185 #define MALLOC_NOMSG(sp, p, cast, size) { \
186 p = (cast)malloc(size); \
188 #define MALLOC_RET(sp, p, cast, size) { \
189 if ((p = (cast)malloc(size)) == NULL) { \
190 msgq(sp, M_SYSERR, NULL); \
191 return (1); \
196 * Resize a buffer, free any already held memory if we can't get more.
197 * FreeBSD's reallocf(3) does the same thing, but it's not portable yet.
199 #define REALLOC(sp, p, cast, size) { \
200 cast newp; \
201 if ((newp = (cast)realloc(p, size)) == NULL) { \
202 if (p != NULL) \
203 free(p); \
204 msgq(sp, M_SYSERR, NULL); \
206 p = newp; \
210 * Versions of bcopy(3) and bzero(3) that use the size of the
211 * initial pointer to figure out how much memory to manipulate.
213 #define BCOPY(p, t, len) bcopy(p, t, (len) * sizeof(*(p)))
214 #define BZERO(p, len) bzero(p, (len) * sizeof(*(p)))
217 * p2roundup --
218 * Get next power of 2; convenient for realloc.
220 * Reference: FreeBSD /usr/src/lib/libc/stdio/getdelim.c
222 static __inline size_t
223 p2roundup(size_t n)
225 n--;
226 n |= n >> 1;
227 n |= n >> 2;
228 n |= n >> 4;
229 n |= n >> 8;
230 n |= n >> 16;
231 #if SIZE_T_MAX > 0xffffffffU
232 n |= n >> 32;
233 #endif
234 n++;
235 return (n);
238 /* Additional TAILQ helper. */
239 #define TAILQ_ENTRY_ISVALID(elm, field) \
240 ((elm)->field.tqe_prev != NULL)