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.
11 #define CHECK_TYPE(type, var) \
12 type L__lp __attribute__((unused)) = var;
14 #define CHECK_TYPE(type, var)
17 /* Increase the size of a malloc'd buffer. Two versions, one that
18 * returns, one that jumps to an error label.
20 #define BINC_GOTO(sp, type, lp, llen, nlen) do { \
21 CHECK_TYPE(type *, lp) \
23 if ((nlen) > llen) { \
24 if ((L__bincp = binc(sp, lp, &(llen), nlen)) == NULL) \
28 * Possible pointer conversion. \
33 #define BINC_GOTOC(sp, lp, llen, nlen) \
34 BINC_GOTO(sp, char, lp, llen, nlen)
35 #define BINC_GOTOW(sp, lp, llen, nlen) \
36 BINC_GOTO(sp, CHAR_T, lp, llen, (nlen) * sizeof(CHAR_T))
37 #define BINC_RET(sp, type, lp, llen, nlen) do { \
38 CHECK_TYPE(type *, lp) \
40 if ((nlen) > llen) { \
41 if ((L__bincp = binc(sp, lp, &(llen), nlen)) == NULL) \
45 * Possible pointer conversion. \
50 #define BINC_RETC(sp, lp, llen, nlen) \
51 BINC_RET(sp, char, lp, llen, nlen)
52 #define BINC_RETW(sp, lp, llen, nlen) \
53 BINC_RET(sp, CHAR_T, lp, llen, (nlen) * sizeof(CHAR_T))
56 * Get some temporary space, preferably from the global temporary buffer,
57 * from a malloc'd buffer otherwise. Two versions, one that returns, one
58 * that jumps to an error label.
60 #define GET_SPACE_GOTO(sp, type, bp, blen, nlen) do { \
61 CHECK_TYPE(type *, bp) \
62 GS *L__gp = (sp) == NULL ? NULL : (sp)->gp; \
63 if (L__gp == NULL || F_ISSET(L__gp, G_TMP_INUSE)) { \
66 BINC_GOTO(sp, type, bp, blen, nlen); \
68 BINC_GOTOC(sp, L__gp->tmp_bp, L__gp->tmp_blen, nlen); \
69 bp = (type *) L__gp->tmp_bp; \
70 blen = L__gp->tmp_blen; \
71 F_SET(L__gp, G_TMP_INUSE); \
74 #define GET_SPACE_GOTOC(sp, bp, blen, nlen) \
75 GET_SPACE_GOTO(sp, char, bp, blen, nlen)
76 #define GET_SPACE_GOTOW(sp, bp, blen, nlen) \
77 GET_SPACE_GOTO(sp, CHAR_T, bp, blen, (nlen) * sizeof(CHAR_T))
78 #define GET_SPACE_RET(sp, type, bp, blen, nlen) do { \
79 CHECK_TYPE(type *, bp) \
80 GS *L__gp = (sp) == NULL ? NULL : (sp)->gp; \
81 if (L__gp == NULL || F_ISSET(L__gp, G_TMP_INUSE)) { \
84 BINC_RET(sp, type, bp, blen, nlen); \
86 BINC_RETC(sp, L__gp->tmp_bp, L__gp->tmp_blen, nlen); \
87 bp = (type *) L__gp->tmp_bp; \
88 blen = L__gp->tmp_blen; \
89 F_SET(L__gp, G_TMP_INUSE); \
92 #define GET_SPACE_RETC(sp, bp, blen, nlen) \
93 GET_SPACE_RET(sp, char, bp, blen, nlen)
94 #define GET_SPACE_RETW(sp, bp, blen, nlen) \
95 GET_SPACE_RET(sp, CHAR_T, bp, blen, (nlen) * sizeof(CHAR_T))
98 * Add space to a GET_SPACE returned buffer. Two versions, one that
99 * returns, one that jumps to an error label.
101 #define ADD_SPACE_GOTO(sp, type, bp, blen, nlen) do { \
102 CHECK_TYPE(type *, bp) \
103 GS *L__gp = (sp) == NULL ? NULL : (sp)->gp; \
104 if (L__gp == NULL || bp == (type *)L__gp->tmp_bp) { \
105 F_CLR(L__gp, G_TMP_INUSE); \
106 BINC_GOTOC(sp, L__gp->tmp_bp, L__gp->tmp_blen, nlen); \
107 bp = (type *) L__gp->tmp_bp; \
108 blen = L__gp->tmp_blen; \
109 F_SET(L__gp, G_TMP_INUSE); \
111 BINC_GOTO(sp, type, bp, blen, nlen); \
113 #define ADD_SPACE_GOTOC(sp, bp, blen, nlen) \
114 ADD_SPACE_GOTO(sp, char, bp, blen, nlen)
115 #define ADD_SPACE_GOTOW(sp, bp, blen, nlen) \
116 ADD_SPACE_GOTO(sp, CHAR_T, bp, blen, (nlen) * sizeof(CHAR_T))
117 #define ADD_SPACE_RET(sp, type, bp, blen, nlen) do { \
118 CHECK_TYPE(type *, bp) \
119 GS *L__gp = (sp) == NULL ? NULL : (sp)->gp; \
120 if (L__gp == NULL || bp == (type *)L__gp->tmp_bp) { \
121 F_CLR(L__gp, G_TMP_INUSE); \
122 BINC_RETC(sp, L__gp->tmp_bp, L__gp->tmp_blen, nlen); \
123 bp = (type *) L__gp->tmp_bp; \
124 blen = L__gp->tmp_blen; \
125 F_SET(L__gp, G_TMP_INUSE); \
127 BINC_RET(sp, type, bp, blen, nlen); \
129 #define ADD_SPACE_RETC(sp, bp, blen, nlen) \
130 ADD_SPACE_RET(sp, char, bp, blen, nlen)
131 #define ADD_SPACE_RETW(sp, bp, blen, nlen) \
132 ADD_SPACE_RET(sp, CHAR_T, bp, blen, (nlen) * sizeof(CHAR_T))
134 /* Free a GET_SPACE returned buffer. */
135 #define FREE_SPACE(sp, bp, blen) do { \
136 GS *L__gp = (sp) == NULL ? NULL : (sp)->gp; \
137 if (L__gp != NULL && bp == L__gp->tmp_bp) \
138 F_CLR(L__gp, G_TMP_INUSE); \
142 #define FREE_SPACEW(sp, bp, blen) do { \
143 CHECK_TYPE(CHAR_T *, bp) \
144 FREE_SPACE(sp, (char *)bp, blen); \
148 * Malloc a buffer, casting the return pointer. Various versions.
150 #define CALLOC(sp, p, nmemb, size) do { \
151 if ((p = calloc(nmemb, size)) == NULL) \
152 msgq(sp, M_SYSERR, NULL); \
154 #define CALLOC_GOTO(sp, p, nmemb, size) do { \
155 if ((p = calloc(nmemb, size)) == NULL) \
158 #define CALLOC_RET(sp, p, nmemb, size) do { \
159 if ((p = calloc(nmemb, size)) == NULL) { \
160 msgq(sp, M_SYSERR, NULL); \
165 #define MALLOC(sp, p, size) do { \
166 if ((p = malloc(size)) == NULL) \
167 msgq(sp, M_SYSERR, NULL); \
169 #define MALLOC_GOTO(sp, p, size) do { \
170 if ((p = malloc(size)) == NULL) \
173 #define MALLOC_RET(sp, p, size) do { \
174 if ((p = malloc(size)) == NULL) { \
175 msgq(sp, M_SYSERR, NULL); \
181 * Resize a buffer, free any already held memory if we can't get more.
182 * FreeBSD's reallocf(3) does the same thing, but it's not portable yet.
184 #define REALLOC(sp, p, cast, size) do { \
186 if ((newp = realloc(p, size)) == NULL) { \
188 msgq(sp, M_SYSERR, NULL); \
195 * Get next power of 2; convenient for realloc.
197 * Reference: FreeBSD /usr/src/lib/libc/stdio/getdelim.c
199 static __inline size_t
208 #if SIZE_T_MAX > 0xffffffffU
215 /* Additional TAILQ helper. */
216 #define TAILQ_ENTRY_ISVALID(elm, field) \
217 ((elm)->field.tqe_prev != NULL)