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