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.13 2002/01/05 23:13:37 skimo Exp $ (Berkeley) $Date: 2002/01/05 23:13:37 $
13 #define CHECK_TYPE(type, var) \
14 type L__lp __attribute__((unused)) = var;
16 #define CHECK_TYPE(type, var)
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, lp, llen, nlen) { \
23 CHECK_TYPE(char *, lp) \
25 if ((nlen) > llen) { \
26 if ((L__bincp = binc(sp, lp, &(llen), nlen)) == NULL) \
30 * Possible pointer conversion. \
35 #define BINC_GOTOW(sp, lp, llen, nlen) { \
36 CHECK_TYPE(CHAR_T *, lp) \
37 BINC_GOTO(sp, (char *)lp, llen, (nlen) * sizeof(CHAR_T)) \
39 #define BINC_RET(sp, lp, llen, nlen) { \
40 CHECK_TYPE(char *, lp) \
42 if ((nlen) > llen) { \
43 if ((L__bincp = binc(sp, lp, &(llen), nlen)) == NULL) \
47 * Possible pointer conversion. \
52 #define BINC_RETW(sp, lp, llen, nlen) { \
53 CHECK_TYPE(CHAR_T *, lp) \
54 BINC_RET(sp, (char *)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, bp, blen, nlen) { \
63 WIN *L__wp = (sp) == NULL ? NULL : (sp)->wp; \
64 if (L__wp == NULL || F_ISSET(L__wp, W_TMP_INUSE)) { \
67 BINC_GOTO(sp, bp, blen, nlen); \
69 BINC_GOTO(sp, L__wp->tmp_bp, L__wp->tmp_blen, nlen); \
71 blen = L__wp->tmp_blen; \
72 F_SET(L__wp, W_TMP_INUSE); \
75 #define GET_SPACE_GOTOW(sp, bp, blen, nlen) { \
77 GET_SPACE_GOTO(sp, (char *)bp, blen, (nlen) * sizeof(CHAR_T)) \
79 #define GET_SPACE_RET(sp, bp, blen, nlen) { \
80 WIN *L__wp = (sp) == NULL ? NULL : (sp)->wp; \
81 if (L__wp == NULL || F_ISSET(L__wp, W_TMP_INUSE)) { \
84 BINC_RET(sp, bp, blen, nlen); \
86 BINC_RET(sp, L__wp->tmp_bp, L__wp->tmp_blen, nlen); \
88 blen = L__wp->tmp_blen; \
89 F_SET(L__wp, W_TMP_INUSE); \
92 #define GET_SPACE_RETW(sp, bp, blen, nlen) { \
93 CHECK_TYPE(CHAR_T *, bp) \
94 GET_SPACE_RET(sp, (char *)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, bp, blen, nlen) { \
102 WIN *L__wp = (sp) == NULL ? NULL : (sp)->wp; \
103 if (L__wp == NULL || bp == L__wp->tmp_bp) { \
104 F_CLR(L__wp, W_TMP_INUSE); \
105 BINC_GOTO(sp, L__wp->tmp_bp, L__wp->tmp_blen, nlen); \
106 bp = L__wp->tmp_bp; \
107 blen = L__wp->tmp_blen; \
108 F_SET(L__wp, W_TMP_INUSE); \
110 BINC_GOTO(sp, bp, blen, nlen); \
112 #define ADD_SPACE_GOTOW(sp, bp, blen, nlen) { \
113 CHECK_TYPE(CHAR_T *, bp) \
114 ADD_SPACE_GOTO(sp, (char *)bp, blen, (nlen) * sizeof(CHAR_T)) \
116 #define ADD_SPACE_RET(sp, bp, blen, nlen) { \
117 WIN *L__wp = (sp) == NULL ? NULL : (sp)->wp; \
118 if (L__wp == NULL || bp == L__wp->tmp_bp) { \
119 F_CLR(L__wp, W_TMP_INUSE); \
120 BINC_RET(sp, L__wp->tmp_bp, L__wp->tmp_blen, nlen); \
121 bp = L__wp->tmp_bp; \
122 blen = L__wp->tmp_blen; \
123 F_SET(L__wp, W_TMP_INUSE); \
125 BINC_RET(sp, bp, blen, nlen); \
127 #define ADD_SPACE_RETW(sp, bp, blen, nlen) { \
128 CHECK_TYPE(CHAR_T *, bp) \
129 ADD_SPACE_RET(sp, (char *)bp, blen, (nlen) * sizeof(CHAR_T)) \
132 /* Free a GET_SPACE returned buffer. */
133 #define FREE_SPACE(sp, bp, blen) { \
134 WIN *L__wp = (sp) == NULL ? NULL : (sp)->wp; \
135 if (L__wp != NULL && bp == L__wp->tmp_bp) \
136 F_CLR(L__wp, W_TMP_INUSE); \
140 #define FREE_SPACEW(sp, bp, blen) { \
141 CHECK_TYPE(CHAR_T *, bp) \
142 FREE_SPACE(sp, (char *)bp, blen); \
146 * Malloc a buffer, casting the return pointer. Various versions.
149 * The cast should be unnecessary, malloc(3) and friends return void *'s,
150 * which is all we need. However, some systems that nvi needs to run on
151 * don't do it right yet, resulting in the compiler printing out roughly
152 * a million warnings. After awhile, it seemed easier to put the casts
153 * in instead of explaining it all the time.
155 #define CALLOC(sp, p, cast, nmemb, size) { \
156 if ((p = (cast)calloc(nmemb, size)) == NULL) \
157 msgq(sp, M_SYSERR, NULL); \
159 #define CALLOC_GOTO(sp, p, cast, nmemb, size) { \
160 if ((p = (cast)calloc(nmemb, size)) == NULL) \
163 #define CALLOC_NOMSG(sp, p, cast, nmemb, size) { \
164 p = (cast)calloc(nmemb, size); \
166 #define CALLOC_RET(sp, p, cast, nmemb, size) { \
167 if ((p = (cast)calloc(nmemb, size)) == NULL) { \
168 msgq(sp, M_SYSERR, NULL); \
173 #define MALLOC(sp, p, cast, size) { \
174 if ((p = (cast)malloc(size)) == NULL) \
175 msgq(sp, M_SYSERR, NULL); \
177 #define MALLOC_GOTO(sp, p, cast, size) { \
178 if ((p = (cast)malloc(size)) == NULL) \
181 #define MALLOC_NOMSG(sp, p, cast, size) { \
182 p = (cast)malloc(size); \
184 #define MALLOC_RET(sp, p, cast, size) { \
185 if ((p = (cast)malloc(size)) == NULL) { \
186 msgq(sp, M_SYSERR, NULL); \
192 * Don't depend on realloc(NULL, size) working.
194 #define REALLOC(sp, p, cast, size) { \
195 if ((p = (cast)(p == NULL ? \
196 malloc(size) : realloc(p, size))) == NULL) \
197 msgq(sp, M_SYSERR, NULL); \
201 * Versions of memmove(3) and memset(3) that use the size of the
202 * initial pointer to figure out how much memory to manipulate.
204 #define MEMMOVE(p, t, len) memmove(p, t, (len) * sizeof(*(p)))
205 #define MEMSET(p, value, len) memset(p, value, (len) * sizeof(*(p)))