1 /* $NetBSD: mem.h,v 1.2 2013/11/22 15:52:05 christos Exp $ */ 2 /*- 3 * Copyright (c) 1993, 1994 4 * The Regents of the University of California. All rights reserved. 5 * Copyright (c) 1993, 1994, 1995, 1996 6 * Keith Bostic. All rights reserved. 7 * 8 * See the LICENSE file for redistribution information. 9 * 10 * Id: mem.h,v 10.13 2002/01/05 23:13:37 skimo Exp (Berkeley) Date: 2002/01/05 23:13:37 11 */ 12 13 #if defined(HAVE_GCC) && !defined(__NetBSD__) && !defined(__minix) 14 #define CHECK_TYPE(type, var) \ 15 do { type L__lp __attribute__((__unused__)) = var; } while (/*CONSTCOND*/0); 16 #else 17 #define CHECK_TYPE(type, var) 18 #endif 19 20 /* Increase the size of a malloc'd buffer. Two versions, one that 21 * returns, one that jumps to an error label. 22 */ 23 #define BINC_GOTO(sp, type, lp, llen, nlen) { \ 24 CHECK_TYPE(type *, lp) \ 25 void *L__bincp; \ 26 if ((nlen) > llen) { \ 27 if ((L__bincp = binc(sp, lp, &(llen), nlen)) == NULL) \ 28 goto alloc_err; \ 29 /* \ 30 * !!! \ 31 * Possible pointer conversion. \ 32 */ \ 33 lp = L__bincp; \ 34 } \ 35 } 36 #define BINC_GOTOC(sp, lp, llen, nlen) \ 37 BINC_GOTO(sp, char, lp, llen, nlen) 38 #define BINC_GOTOW(sp, lp, llen, nlen) \ 39 BINC_GOTO(sp, CHAR_T, lp, llen, (nlen) * sizeof(CHAR_T)) 40 #define BINC_RET(sp, type, lp, llen, nlen) { \ 41 CHECK_TYPE(type *, lp) \ 42 void *L__bincp; \ 43 if ((size_t)(nlen) > llen) { \ 44 if ((L__bincp = binc(sp, lp, &(llen), nlen)) == NULL) \ 45 return (1); \ 46 /* \ 47 * !!! \ 48 * Possible pointer conversion. \ 49 */ \ 50 lp = L__bincp; \ 51 } \ 52 } 53 #define BINC_RETC(sp, lp, llen, nlen) \ 54 BINC_RET(sp, char, lp, llen, nlen) 55 #define BINC_RETW(sp, lp, llen, nlen) \ 56 BINC_RET(sp, CHAR_T, lp, llen, (nlen) * sizeof(CHAR_T)) 57 58 /* 59 * Get some temporary space, preferably from the global temporary buffer, 60 * from a malloc'd buffer otherwise. Two versions, one that returns, one 61 * that jumps to an error label. 62 */ 63 #define GET_SPACE_GOTO(sp, type, bp, blen, nlen) { \ 64 CHECK_TYPE(type *, bp) \ 65 WIN *L__wp = (sp) == NULL ? NULL : (sp)->wp; \ 66 if (L__wp == NULL || F_ISSET(L__wp, W_TMP_INUSE)) { \ 67 bp = NULL; \ 68 blen = 0; \ 69 BINC_GOTO(sp, type, bp, blen, nlen); \ 70 } else { \ 71 BINC_GOTOC(sp, L__wp->tmp_bp, L__wp->tmp_blen, nlen); \ 72 bp = (type *) L__wp->tmp_bp; \ 73 blen = L__wp->tmp_blen; \ 74 F_SET(L__wp, W_TMP_INUSE); \ 75 } \ 76 } 77 #define GET_SPACE_GOTOC(sp, bp, blen, nlen) \ 78 GET_SPACE_GOTO(sp, char, bp, blen, nlen) 79 #define GET_SPACE_GOTOW(sp, bp, blen, nlen) \ 80 GET_SPACE_GOTO(sp, CHAR_T, bp, blen, (nlen) * sizeof(CHAR_T)) 81 #define GET_SPACE_RET(sp, type, bp, blen, nlen) { \ 82 CHECK_TYPE(type *, bp) \ 83 WIN *L__wp = (sp) == NULL ? NULL : (sp)->wp; \ 84 if (L__wp == NULL || F_ISSET(L__wp, W_TMP_INUSE)) { \ 85 bp = NULL; \ 86 blen = 0; \ 87 BINC_RET(sp, type, bp, blen, nlen); \ 88 } else { \ 89 BINC_RETC(sp, L__wp->tmp_bp, L__wp->tmp_blen, nlen); \ 90 bp = (type *) L__wp->tmp_bp; \ 91 blen = L__wp->tmp_blen; \ 92 F_SET(L__wp, W_TMP_INUSE); \ 93 } \ 94 } 95 #define GET_SPACE_RETC(sp, bp, blen, nlen) \ 96 GET_SPACE_RET(sp, char, bp, blen, nlen) 97 #define GET_SPACE_RETW(sp, bp, blen, nlen) \ 98 GET_SPACE_RET(sp, CHAR_T, bp, blen, (nlen) * sizeof(CHAR_T)) 99 100 /* 101 * Add space to a GET_SPACE returned buffer. Two versions, one that 102 * returns, one that jumps to an error label. 103 */ 104 #define ADD_SPACE_GOTO(sp, type, bp, blen, nlen) { \ 105 WIN *L__wp = (sp) == NULL ? NULL : (sp)->wp; \ 106 CHECK_TYPE(type *, bp) \ 107 if (L__wp == NULL || bp == (type *)L__wp->tmp_bp) { \ 108 F_CLR(L__wp, W_TMP_INUSE); \ 109 BINC_GOTOC(sp, L__wp->tmp_bp, L__wp->tmp_blen, nlen); \ 110 bp = (type *) L__wp->tmp_bp; \ 111 blen = L__wp->tmp_blen; \ 112 F_SET(L__wp, W_TMP_INUSE); \ 113 } else \ 114 BINC_GOTO(sp, type, bp, blen, nlen); \ 115 } 116 #define ADD_SPACE_GOTOW(sp, bp, blen, nlen) \ 117 ADD_SPACE_GOTO(sp, CHAR_T, bp, blen, (nlen) * sizeof(CHAR_T)) 118 #define ADD_SPACE_RET(sp, type, bp, blen, nlen) { \ 119 CHECK_TYPE(type *, bp) \ 120 WIN *L__wp = (sp) == NULL ? NULL : (sp)->wp; \ 121 if (L__wp == NULL || bp == (type *)L__wp->tmp_bp) { \ 122 F_CLR(L__wp, W_TMP_INUSE); \ 123 BINC_RETC(sp, L__wp->tmp_bp, L__wp->tmp_blen, nlen); \ 124 bp = (type *) L__wp->tmp_bp; \ 125 blen = L__wp->tmp_blen; \ 126 F_SET(L__wp, W_TMP_INUSE); \ 127 } else \ 128 BINC_RET(sp, type, bp, blen, nlen); \ 129 } 130 #define ADD_SPACE_RETW(sp, bp, blen, nlen) \ 131 ADD_SPACE_RET(sp, CHAR_T, bp, blen, (nlen) * sizeof(CHAR_T)) 132 133 /* Free a GET_SPACE returned buffer. */ 134 #define FREE_SPACE(sp, bp, blen) { \ 135 WIN *L__wp = (sp) == NULL ? NULL : (sp)->wp; \ 136 if (L__wp != NULL && bp == L__wp->tmp_bp) \ 137 F_CLR(L__wp, W_TMP_INUSE); \ 138 else \ 139 free(bp); \ 140 } 141 #define FREE_SPACEW(sp, bp, blen) { \ 142 CHECK_TYPE(CHAR_T *, bp) \ 143 FREE_SPACE(sp, (char *)bp, blen); \ 144 } 145 146 /* 147 * Malloc a buffer, casting the return pointer. Various versions. 148 * 149 * !!! 150 * The cast should be unnecessary, malloc(3) and friends return void *'s, 151 * which is all we need. However, some systems that nvi needs to run on 152 * don't do it right yet, resulting in the compiler printing out roughly 153 * a million warnings. After awhile, it seemed easier to put the casts 154 * in instead of explaining it all the time. 155 */ 156 #define CALLOC(sp, p, cast, nmemb, size) { \ 157 if ((p = (cast)calloc(nmemb, size)) == NULL) \ 158 msgq(sp, M_SYSERR, NULL); \ 159 } 160 #define CALLOC_GOTO(sp, p, cast, nmemb, size) { \ 161 if ((p = (cast)calloc(nmemb, size)) == NULL) \ 162 goto alloc_err; \ 163 } 164 #define CALLOC_NOMSG(sp, p, cast, nmemb, size) { \ 165 p = (cast)calloc(nmemb, size); \ 166 } 167 #define CALLOC_RET(sp, p, cast, nmemb, size) { \ 168 if ((p = (cast)calloc(nmemb, size)) == NULL) { \ 169 msgq(sp, M_SYSERR, NULL); \ 170 return (1); \ 171 } \ 172 } 173 174 #define MALLOC(sp, p, cast, size) { \ 175 if ((p = (cast)malloc(size)) == NULL) \ 176 msgq(sp, M_SYSERR, NULL); \ 177 } 178 #define MALLOC_GOTO(sp, p, cast, size) { \ 179 if ((p = (cast)malloc(size)) == NULL) \ 180 goto alloc_err; \ 181 } 182 #define MALLOC_NOMSG(sp, p, cast, size) { \ 183 p = (cast)malloc(size); \ 184 } 185 #define MALLOC_RET(sp, p, cast, size) { \ 186 if ((p = (cast)malloc(size)) == NULL) { \ 187 msgq(sp, M_SYSERR, NULL); \ 188 return (1); \ 189 } \ 190 } 191 /* 192 * XXX 193 * Don't depend on realloc(NULL, size) working. 194 */ 195 #define REALLOC(sp, p, cast, size) { \ 196 if ((p = (cast)(p == NULL ? \ 197 malloc(size) : realloc(p, size))) == NULL) \ 198 msgq(sp, M_SYSERR, NULL); \ 199 } 200 201 /* 202 * Versions of memmove(3) and memset(3) that use the size of the 203 * initial pointer to figure out how much memory to manipulate. 204 */ 205 #define MEMMOVE(p, t, len) memmove(p, t, (len) * sizeof(*(p))) 206 #define MEMSET(p, value, len) memset(p, value, (len) * sizeof(*(p))) 207