1 /* $OpenBSD: mem.h,v 1.10 2017/06/24 16:30:47 martijn 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 #define CALLOC(sp, p, nmemb, size) { \ 116 if (((p) = calloc((nmemb), (size))) == NULL) \ 117 msgq((sp), M_SYSERR, NULL); \ 118 } 119 #define CALLOC_GOTO(sp, p, nmemb, size) { \ 120 if (((p) = calloc((nmemb), (size))) == NULL) \ 121 goto alloc_err; \ 122 } 123 #define CALLOC_RET(sp, p, nmemb, size) { \ 124 if (((p) = calloc((nmemb), (size))) == NULL) { \ 125 msgq((sp), M_SYSERR, NULL); \ 126 return (1); \ 127 } \ 128 } 129 130 #define MALLOC(sp, p, size) { \ 131 if (((p) = malloc(size)) == NULL) \ 132 msgq((sp), M_SYSERR, NULL); \ 133 } 134 #define MALLOC_GOTO(sp, p, size) { \ 135 if (((p) = malloc(size)) == NULL) \ 136 goto alloc_err; \ 137 } 138 #define MALLOC_RET(sp, p, size) { \ 139 if (((p) = malloc(size)) == NULL) { \ 140 msgq((sp), M_SYSERR, NULL); \ 141 return (1); \ 142 } \ 143 } 144 145 #define REALLOC(sp, p, size) { \ 146 void *tmpp; \ 147 if (((tmpp) = (realloc((p), (size)))) == NULL) { \ 148 msgq((sp), M_SYSERR, NULL); \ 149 free(p); \ 150 } \ 151 p = tmpp; \ 152 } 153 154 #define REALLOCARRAY(sp, p, nelem, size) { \ 155 void *tmpp; \ 156 if (((tmpp) = (reallocarray((p), (nelem), (size)))) == NULL) { \ 157 msgq((sp), M_SYSERR, NULL); \ 158 free(p); \ 159 } \ 160 p = tmpp; \ 161 } 162 163 /* 164 * Versions of memmove(3) and memset(3) that use the size of the 165 * initial pointer to figure out how much memory to manipulate. 166 */ 167 #define MEMMOVE(p, t, len) memmove((p), (t), (len) * sizeof(*(p))) 168 #define MEMSET(p, value, len) memset((p), (value), (len) * sizeof(*(p))) 169