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