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