xref: /freebsd/contrib/nvi/common/mem.h (revision 39beb93c)
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