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