Merge from vendor branch LESS:
[dragonfly.git] / contrib / nvi / common / mem.h
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)))