1 /* $OpenBSD: mem.h,v 1.5 2006/01/08 21:05:39 miod 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 * @(#)mem.h 10.7 (Berkeley) 3/30/96 12 */ 13 14 /* Increase the size of a malloc'd buffer. Two versions, one that 15 * returns, one that jumps to an error label. 16 */ 17 #define BINC_GOTO(sp, lp, llen, nlen) { \ 18 void *L__bincp; \ 19 if ((nlen) > (llen)) { \ 20 if ((L__bincp = binc((sp), (lp), &(llen), (nlen))) \ 21 == NULL) \ 22 goto alloc_err; \ 23 /* \ 24 * !!! \ 25 * Possible pointer conversion. \ 26 */ \ 27 (lp) = L__bincp; \ 28 } \ 29 } 30 #define BINC_RET(sp, lp, llen, nlen) { \ 31 void *L__bincp; \ 32 if ((nlen) > (llen)) { \ 33 if ((L__bincp = binc((sp), (lp), &(llen), (nlen))) \ 34 == NULL) \ 35 return (1); \ 36 /* \ 37 * !!! \ 38 * Possible pointer conversion. \ 39 */ \ 40 (lp) = L__bincp; \ 41 } \ 42 } 43 44 /* 45 * Get some temporary space, preferably from the global temporary buffer, 46 * from a malloc'd buffer otherwise. Two versions, one that returns, one 47 * that jumps to an error label. 48 */ 49 #define GET_SPACE_GOTO(sp, bp, blen, nlen) { \ 50 GS *L__gp = (sp) == NULL ? NULL : (sp)->gp; \ 51 if (L__gp == NULL || F_ISSET(L__gp, G_TMP_INUSE)) { \ 52 (bp) = NULL; \ 53 (blen) = 0; \ 54 BINC_GOTO((sp), (bp), (blen), (nlen)); \ 55 } else { \ 56 BINC_GOTO((sp), L__gp->tmp_bp, L__gp->tmp_blen, (nlen));\ 57 (bp) = L__gp->tmp_bp; \ 58 (blen) = L__gp->tmp_blen; \ 59 F_SET(L__gp, G_TMP_INUSE); \ 60 } \ 61 } 62 #define GET_SPACE_RET(sp, bp, blen, nlen) { \ 63 GS *L__gp = (sp) == NULL ? NULL : (sp)->gp; \ 64 if (L__gp == NULL || F_ISSET(L__gp, G_TMP_INUSE)) { \ 65 (bp) = NULL; \ 66 (blen) = 0; \ 67 BINC_RET((sp), (bp), (blen), (nlen)); \ 68 } else { \ 69 BINC_RET((sp), L__gp->tmp_bp, L__gp->tmp_blen, (nlen)); \ 70 (bp) = L__gp->tmp_bp; \ 71 (blen) = L__gp->tmp_blen; \ 72 F_SET(L__gp, G_TMP_INUSE); \ 73 } \ 74 } 75 76 /* 77 * Add space to a GET_SPACE returned buffer. Two versions, one that 78 * returns, one that jumps to an error label. 79 */ 80 #define ADD_SPACE_GOTO(sp, bp, blen, nlen) { \ 81 GS *L__gp = (sp) == NULL ? NULL : (sp)->gp; \ 82 if (L__gp == NULL || (bp) == L__gp->tmp_bp) { \ 83 F_CLR(L__gp, G_TMP_INUSE); \ 84 BINC_GOTO((sp), L__gp->tmp_bp, L__gp->tmp_blen, (nlen));\ 85 (bp) = L__gp->tmp_bp; \ 86 (blen) = L__gp->tmp_blen; \ 87 F_SET(L__gp, G_TMP_INUSE); \ 88 } else \ 89 BINC_GOTO((sp), (bp), (blen), (nlen)); \ 90 } 91 #define ADD_SPACE_RET(sp, bp, blen, nlen) { \ 92 GS *L__gp = (sp) == NULL ? NULL : (sp)->gp; \ 93 if (L__gp == NULL || (bp) == L__gp->tmp_bp) { \ 94 F_CLR(L__gp, G_TMP_INUSE); \ 95 BINC_RET((sp), L__gp->tmp_bp, L__gp->tmp_blen, (nlen)); \ 96 (bp) = L__gp->tmp_bp; \ 97 (blen) = L__gp->tmp_blen; \ 98 F_SET(L__gp, G_TMP_INUSE); \ 99 } else \ 100 BINC_RET((sp), (bp), (blen), (nlen)); \ 101 } 102 103 /* Free a GET_SPACE returned buffer. */ 104 #define FREE_SPACE(sp, bp, blen) { \ 105 GS *L__gp = (sp) == NULL ? NULL : (sp)->gp; \ 106 if (L__gp != NULL && (bp) == L__gp->tmp_bp) \ 107 F_CLR(L__gp, G_TMP_INUSE); \ 108 else \ 109 free(bp); \ 110 } 111 112 /* 113 * Malloc a buffer, casting the return pointer. Various versions. 114 * 115 * !!! 116 * The cast should be unnecessary, malloc(3) and friends return void *'s, 117 * which is all we need. However, some systems that nvi needs to run on 118 * don't do it right yet, resulting in the compiler printing out roughly 119 * a million warnings. After awhile, it seemed easier to put the casts 120 * in instead of explaining it all the time. 121 */ 122 #define CALLOC(sp, p, cast, nmemb, size) { \ 123 if (((p) = (cast)calloc((nmemb), (size))) == NULL) \ 124 msgq((sp), M_SYSERR, NULL); \ 125 } 126 #define CALLOC_GOTO(sp, p, cast, nmemb, size) { \ 127 if (((p) = (cast)calloc((nmemb), (size))) == NULL) \ 128 goto alloc_err; \ 129 } 130 #define CALLOC_NOMSG(sp, p, cast, nmemb, size) { \ 131 (p) = (cast)calloc((nmemb), (size)); \ 132 } 133 #define CALLOC_RET(sp, p, cast, nmemb, size) { \ 134 if (((p) = (cast)calloc((nmemb), (size))) == NULL) { \ 135 msgq((sp), M_SYSERR, NULL); \ 136 return (1); \ 137 } \ 138 } 139 140 #define MALLOC(sp, p, cast, size) { \ 141 if (((p) = (cast)malloc(size)) == NULL) \ 142 msgq((sp), M_SYSERR, NULL); \ 143 } 144 #define MALLOC_GOTO(sp, p, cast, size) { \ 145 if (((p) = (cast)malloc(size)) == NULL) \ 146 goto alloc_err; \ 147 } 148 #define MALLOC_NOMSG(sp, p, cast, size) { \ 149 (p) = (cast)malloc(size); \ 150 } 151 #define MALLOC_RET(sp, p, cast, size) { \ 152 if (((p) = (cast)malloc(size)) == NULL) { \ 153 msgq((sp), M_SYSERR, NULL); \ 154 return (1); \ 155 } \ 156 } 157 /* 158 * XXX 159 * Don't depend on realloc(NULL, size) working. 160 */ 161 #define REALLOC(sp, p, cast, size) { \ 162 if (((p) = (cast)((p) == NULL ? \ 163 malloc(size) : realloc((p), (size)))) == NULL) \ 164 msgq((sp), M_SYSERR, NULL); \ 165 } 166 167 /* 168 * Versions of memmove(3) and memset(3) that use the size of the 169 * initial pointer to figure out how much memory to manipulate. 170 */ 171 #define MEMMOVE(p, t, len) memmove((p), (t), (len) * sizeof(*(p))) 172 #define MEMSET(p, value, len) memset((p), (value), (len) * sizeof(*(p))) 173