1/* $NetBSD: mem.h,v 1.3 2017/11/21 02:04:39 rin 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__) 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 ((size_t)(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