xref: /openbsd/usr.bin/vi/common/mem.h (revision 3d8817e4)
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