1*86d7f5d3SJohn Marino /* obstack.c - subroutines used implicitly by object stack macros
2*86d7f5d3SJohn Marino Copyright (C) 1988,89,90,91,92,93,94,96,97 Free Software Foundation, Inc.
3*86d7f5d3SJohn Marino
4*86d7f5d3SJohn Marino
5*86d7f5d3SJohn Marino NOTE: This source is derived from an old version taken from the GNU C
6*86d7f5d3SJohn Marino Library (glibc).
7*86d7f5d3SJohn Marino
8*86d7f5d3SJohn Marino This program is free software; you can redistribute it and/or modify it
9*86d7f5d3SJohn Marino under the terms of the GNU General Public License as published by the
10*86d7f5d3SJohn Marino Free Software Foundation; either version 2, or (at your option) any
11*86d7f5d3SJohn Marino later version.
12*86d7f5d3SJohn Marino
13*86d7f5d3SJohn Marino This program is distributed in the hope that it will be useful,
14*86d7f5d3SJohn Marino but WITHOUT ANY WARRANTY; without even the implied warranty of
15*86d7f5d3SJohn Marino MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16*86d7f5d3SJohn Marino GNU General Public License for more details.
17*86d7f5d3SJohn Marino
18*86d7f5d3SJohn Marino You should have received a copy of the GNU General Public License
19*86d7f5d3SJohn Marino along with this program; if not, write to the Free Software
20*86d7f5d3SJohn Marino Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301,
21*86d7f5d3SJohn Marino USA. */
22*86d7f5d3SJohn Marino
23*86d7f5d3SJohn Marino #ifdef HAVE_CONFIG_H
24*86d7f5d3SJohn Marino #include <config.h>
25*86d7f5d3SJohn Marino #endif
26*86d7f5d3SJohn Marino
27*86d7f5d3SJohn Marino #include "obstack.h"
28*86d7f5d3SJohn Marino
29*86d7f5d3SJohn Marino /* NOTE BEFORE MODIFYING THIS FILE: This version number must be
30*86d7f5d3SJohn Marino incremented whenever callers compiled using an old obstack.h can no
31*86d7f5d3SJohn Marino longer properly call the functions in this obstack.c. */
32*86d7f5d3SJohn Marino #define OBSTACK_INTERFACE_VERSION 1
33*86d7f5d3SJohn Marino
34*86d7f5d3SJohn Marino /* Comment out all this code if we are using the GNU C Library, and are not
35*86d7f5d3SJohn Marino actually compiling the library itself, and the installed library
36*86d7f5d3SJohn Marino supports the same library interface we do. This code is part of the GNU
37*86d7f5d3SJohn Marino C Library, but also included in many other GNU distributions. Compiling
38*86d7f5d3SJohn Marino and linking in this code is a waste when using the GNU C library
39*86d7f5d3SJohn Marino (especially if it is a shared library). Rather than having every GNU
40*86d7f5d3SJohn Marino program understand `configure --with-gnu-libc' and omit the object
41*86d7f5d3SJohn Marino files, it is simpler to just do this in the source for each such file. */
42*86d7f5d3SJohn Marino
43*86d7f5d3SJohn Marino #include <stdio.h> /* Random thing to get __GNU_LIBRARY__. */
44*86d7f5d3SJohn Marino #if !defined (_LIBC) && defined (__GNU_LIBRARY__) && __GNU_LIBRARY__ > 1
45*86d7f5d3SJohn Marino #include <gnu-versions.h>
46*86d7f5d3SJohn Marino #if _GNU_OBSTACK_INTERFACE_VERSION == OBSTACK_INTERFACE_VERSION
47*86d7f5d3SJohn Marino #define ELIDE_CODE
48*86d7f5d3SJohn Marino #endif
49*86d7f5d3SJohn Marino #endif
50*86d7f5d3SJohn Marino
51*86d7f5d3SJohn Marino
52*86d7f5d3SJohn Marino #ifndef ELIDE_CODE
53*86d7f5d3SJohn Marino
54*86d7f5d3SJohn Marino
55*86d7f5d3SJohn Marino #define POINTER void *
56*86d7f5d3SJohn Marino
57*86d7f5d3SJohn Marino /* Determine default alignment. */
58*86d7f5d3SJohn Marino struct fooalign {char x; double d;};
59*86d7f5d3SJohn Marino #define DEFAULT_ALIGNMENT \
60*86d7f5d3SJohn Marino ((PTR_INT_TYPE) ((char *) &((struct fooalign *) 0)->d - (char *) 0))
61*86d7f5d3SJohn Marino /* If malloc were really smart, it would round addresses to DEFAULT_ALIGNMENT.
62*86d7f5d3SJohn Marino But in fact it might be less smart and round addresses to as much as
63*86d7f5d3SJohn Marino DEFAULT_ROUNDING. So we prepare for it to do that. */
64*86d7f5d3SJohn Marino union fooround {long x; double d;};
65*86d7f5d3SJohn Marino #define DEFAULT_ROUNDING (sizeof (union fooround))
66*86d7f5d3SJohn Marino
67*86d7f5d3SJohn Marino /* When we copy a long block of data, this is the unit to do it with.
68*86d7f5d3SJohn Marino On some machines, copying successive ints does not work;
69*86d7f5d3SJohn Marino in such a case, redefine COPYING_UNIT to `long' (if that works)
70*86d7f5d3SJohn Marino or `char' as a last resort. */
71*86d7f5d3SJohn Marino #ifndef COPYING_UNIT
72*86d7f5d3SJohn Marino #define COPYING_UNIT int
73*86d7f5d3SJohn Marino #endif
74*86d7f5d3SJohn Marino
75*86d7f5d3SJohn Marino
76*86d7f5d3SJohn Marino /* The functions allocating more room by calling `obstack_chunk_alloc'
77*86d7f5d3SJohn Marino jump to the handler pointed to by `obstack_alloc_failed_handler'.
78*86d7f5d3SJohn Marino This variable by default points to the internal function
79*86d7f5d3SJohn Marino `print_and_abort'. */
80*86d7f5d3SJohn Marino static void print_and_abort (void);
81*86d7f5d3SJohn Marino void (*obstack_alloc_failed_handler) (void) = print_and_abort;
82*86d7f5d3SJohn Marino
83*86d7f5d3SJohn Marino /* Exit value used when `print_and_abort' is used. */
84*86d7f5d3SJohn Marino #if defined __GNU_LIBRARY__ || defined HAVE_STDLIB_H
85*86d7f5d3SJohn Marino #include <stdlib.h>
86*86d7f5d3SJohn Marino #endif
87*86d7f5d3SJohn Marino #ifndef EXIT_FAILURE
88*86d7f5d3SJohn Marino #define EXIT_FAILURE 1
89*86d7f5d3SJohn Marino #endif
90*86d7f5d3SJohn Marino int obstack_exit_failure = EXIT_FAILURE;
91*86d7f5d3SJohn Marino
92*86d7f5d3SJohn Marino /* The non-GNU-C macros copy the obstack into this global variable
93*86d7f5d3SJohn Marino to avoid multiple evaluation. */
94*86d7f5d3SJohn Marino
95*86d7f5d3SJohn Marino struct obstack *_obstack;
96*86d7f5d3SJohn Marino
97*86d7f5d3SJohn Marino /* Define a macro that either calls functions with the traditional malloc/free
98*86d7f5d3SJohn Marino calling interface, or calls functions with the mmalloc/mfree interface
99*86d7f5d3SJohn Marino (that adds an extra first argument), based on the state of use_extra_arg.
100*86d7f5d3SJohn Marino For free, do not use ?:, since some compilers, like the MIPS compilers,
101*86d7f5d3SJohn Marino do not allow (expr) ? void : void. */
102*86d7f5d3SJohn Marino
103*86d7f5d3SJohn Marino #if defined (__STDC__) && __STDC__
104*86d7f5d3SJohn Marino #define CALL_CHUNKFUN(h, size) \
105*86d7f5d3SJohn Marino (((h) -> use_extra_arg) \
106*86d7f5d3SJohn Marino ? (*(h)->chunkfun) ((h)->extra_arg, (size)) \
107*86d7f5d3SJohn Marino : (*(struct _obstack_chunk *(*) (long)) (h)->chunkfun) ((size)))
108*86d7f5d3SJohn Marino
109*86d7f5d3SJohn Marino #define CALL_FREEFUN(h, old_chunk) \
110*86d7f5d3SJohn Marino do { \
111*86d7f5d3SJohn Marino if ((h) -> use_extra_arg) \
112*86d7f5d3SJohn Marino (*(h)->freefun) ((h)->extra_arg, (old_chunk)); \
113*86d7f5d3SJohn Marino else \
114*86d7f5d3SJohn Marino (*(void (*) (void *)) (h)->freefun) ((old_chunk)); \
115*86d7f5d3SJohn Marino } while (0)
116*86d7f5d3SJohn Marino #else
117*86d7f5d3SJohn Marino #define CALL_CHUNKFUN(h, size) \
118*86d7f5d3SJohn Marino (((h) -> use_extra_arg) \
119*86d7f5d3SJohn Marino ? (*(h)->chunkfun) ((h)->extra_arg, (size)) \
120*86d7f5d3SJohn Marino : (*(struct _obstack_chunk *(*) ()) (h)->chunkfun) ((size)))
121*86d7f5d3SJohn Marino
122*86d7f5d3SJohn Marino #define CALL_FREEFUN(h, old_chunk) \
123*86d7f5d3SJohn Marino do { \
124*86d7f5d3SJohn Marino if ((h) -> use_extra_arg) \
125*86d7f5d3SJohn Marino (*(h)->freefun) ((h)->extra_arg, (old_chunk)); \
126*86d7f5d3SJohn Marino else \
127*86d7f5d3SJohn Marino (*(void (*) ()) (h)->freefun) ((old_chunk)); \
128*86d7f5d3SJohn Marino } while (0)
129*86d7f5d3SJohn Marino #endif
130*86d7f5d3SJohn Marino
131*86d7f5d3SJohn Marino
132*86d7f5d3SJohn Marino /* Initialize an obstack H for use. Specify chunk size SIZE (0 means default).
133*86d7f5d3SJohn Marino Objects start on multiples of ALIGNMENT (0 means use default).
134*86d7f5d3SJohn Marino CHUNKFUN is the function to use to allocate chunks,
135*86d7f5d3SJohn Marino and FREEFUN the function to free them.
136*86d7f5d3SJohn Marino
137*86d7f5d3SJohn Marino Return nonzero if successful, zero if out of memory.
138*86d7f5d3SJohn Marino To recover from an out of memory error,
139*86d7f5d3SJohn Marino free up some memory, then call this again. */
140*86d7f5d3SJohn Marino
141*86d7f5d3SJohn Marino int
_obstack_begin(struct obstack * h,int size,int alignment,POINTER (* chunkfun)(long),void (* freefun)(void *))142*86d7f5d3SJohn Marino _obstack_begin (struct obstack *h, int size, int alignment,
143*86d7f5d3SJohn Marino POINTER (*chunkfun) (long), void (*freefun) (void *))
144*86d7f5d3SJohn Marino {
145*86d7f5d3SJohn Marino register struct _obstack_chunk *chunk; /* points to new chunk */
146*86d7f5d3SJohn Marino
147*86d7f5d3SJohn Marino if (alignment == 0)
148*86d7f5d3SJohn Marino alignment = (int) DEFAULT_ALIGNMENT;
149*86d7f5d3SJohn Marino if (size == 0)
150*86d7f5d3SJohn Marino /* Default size is what GNU malloc can fit in a 4096-byte block. */
151*86d7f5d3SJohn Marino {
152*86d7f5d3SJohn Marino /* 12 is sizeof (mhead) and 4 is EXTRA from GNU malloc.
153*86d7f5d3SJohn Marino Use the values for range checking, because if range checking is off,
154*86d7f5d3SJohn Marino the extra bytes won't be missed terribly, but if range checking is on
155*86d7f5d3SJohn Marino and we used a larger request, a whole extra 4096 bytes would be
156*86d7f5d3SJohn Marino allocated.
157*86d7f5d3SJohn Marino
158*86d7f5d3SJohn Marino These number are irrelevant to the new GNU malloc. I suspect it is
159*86d7f5d3SJohn Marino less sensitive to the size of the request. */
160*86d7f5d3SJohn Marino int extra = ((((12 + DEFAULT_ROUNDING - 1) & ~(DEFAULT_ROUNDING - 1))
161*86d7f5d3SJohn Marino + 4 + DEFAULT_ROUNDING - 1)
162*86d7f5d3SJohn Marino & ~(DEFAULT_ROUNDING - 1));
163*86d7f5d3SJohn Marino size = 4096 - extra;
164*86d7f5d3SJohn Marino }
165*86d7f5d3SJohn Marino
166*86d7f5d3SJohn Marino h->chunkfun = (struct _obstack_chunk * (*)(void *, long)) chunkfun;
167*86d7f5d3SJohn Marino h->freefun = (void (*) (void *, struct _obstack_chunk *)) freefun;
168*86d7f5d3SJohn Marino h->chunk_size = size;
169*86d7f5d3SJohn Marino h->alignment_mask = alignment - 1;
170*86d7f5d3SJohn Marino h->use_extra_arg = 0;
171*86d7f5d3SJohn Marino
172*86d7f5d3SJohn Marino chunk = h->chunk = CALL_CHUNKFUN (h, h -> chunk_size);
173*86d7f5d3SJohn Marino if (!chunk)
174*86d7f5d3SJohn Marino (*obstack_alloc_failed_handler) ();
175*86d7f5d3SJohn Marino h->next_free = h->object_base = chunk->contents;
176*86d7f5d3SJohn Marino h->chunk_limit = chunk->limit
177*86d7f5d3SJohn Marino = (char *) chunk + h->chunk_size;
178*86d7f5d3SJohn Marino chunk->prev = 0;
179*86d7f5d3SJohn Marino /* The initial chunk now contains no empty object. */
180*86d7f5d3SJohn Marino h->maybe_empty_object = 0;
181*86d7f5d3SJohn Marino h->alloc_failed = 0;
182*86d7f5d3SJohn Marino return 1;
183*86d7f5d3SJohn Marino }
184*86d7f5d3SJohn Marino
185*86d7f5d3SJohn Marino int
_obstack_begin_1(struct obstack * h,int size,int alignment,POINTER (* chunkfun)(POINTER,long),void (* freefun)(POINTER,POINTER),POINTER arg)186*86d7f5d3SJohn Marino _obstack_begin_1 (struct obstack *h, int size, int alignment,
187*86d7f5d3SJohn Marino POINTER (*chunkfun) (POINTER, long),
188*86d7f5d3SJohn Marino void (*freefun) (POINTER, POINTER), POINTER arg)
189*86d7f5d3SJohn Marino {
190*86d7f5d3SJohn Marino register struct _obstack_chunk *chunk; /* points to new chunk */
191*86d7f5d3SJohn Marino
192*86d7f5d3SJohn Marino if (alignment == 0)
193*86d7f5d3SJohn Marino alignment = (int) DEFAULT_ALIGNMENT;
194*86d7f5d3SJohn Marino if (size == 0)
195*86d7f5d3SJohn Marino /* Default size is what GNU malloc can fit in a 4096-byte block. */
196*86d7f5d3SJohn Marino {
197*86d7f5d3SJohn Marino /* 12 is sizeof (mhead) and 4 is EXTRA from GNU malloc.
198*86d7f5d3SJohn Marino Use the values for range checking, because if range checking is off,
199*86d7f5d3SJohn Marino the extra bytes won't be missed terribly, but if range checking is on
200*86d7f5d3SJohn Marino and we used a larger request, a whole extra 4096 bytes would be
201*86d7f5d3SJohn Marino allocated.
202*86d7f5d3SJohn Marino
203*86d7f5d3SJohn Marino These number are irrelevant to the new GNU malloc. I suspect it is
204*86d7f5d3SJohn Marino less sensitive to the size of the request. */
205*86d7f5d3SJohn Marino int extra = ((((12 + DEFAULT_ROUNDING - 1) & ~(DEFAULT_ROUNDING - 1))
206*86d7f5d3SJohn Marino + 4 + DEFAULT_ROUNDING - 1)
207*86d7f5d3SJohn Marino & ~(DEFAULT_ROUNDING - 1));
208*86d7f5d3SJohn Marino size = 4096 - extra;
209*86d7f5d3SJohn Marino }
210*86d7f5d3SJohn Marino
211*86d7f5d3SJohn Marino h->chunkfun = (struct _obstack_chunk * (*)(void *,long)) chunkfun;
212*86d7f5d3SJohn Marino h->freefun = (void (*) (void *, struct _obstack_chunk *)) freefun;
213*86d7f5d3SJohn Marino h->chunk_size = size;
214*86d7f5d3SJohn Marino h->alignment_mask = alignment - 1;
215*86d7f5d3SJohn Marino h->extra_arg = arg;
216*86d7f5d3SJohn Marino h->use_extra_arg = 1;
217*86d7f5d3SJohn Marino
218*86d7f5d3SJohn Marino chunk = h->chunk = CALL_CHUNKFUN (h, h -> chunk_size);
219*86d7f5d3SJohn Marino if (!chunk)
220*86d7f5d3SJohn Marino (*obstack_alloc_failed_handler) ();
221*86d7f5d3SJohn Marino h->next_free = h->object_base = chunk->contents;
222*86d7f5d3SJohn Marino h->chunk_limit = chunk->limit
223*86d7f5d3SJohn Marino = (char *) chunk + h->chunk_size;
224*86d7f5d3SJohn Marino chunk->prev = 0;
225*86d7f5d3SJohn Marino /* The initial chunk now contains no empty object. */
226*86d7f5d3SJohn Marino h->maybe_empty_object = 0;
227*86d7f5d3SJohn Marino h->alloc_failed = 0;
228*86d7f5d3SJohn Marino return 1;
229*86d7f5d3SJohn Marino }
230*86d7f5d3SJohn Marino
231*86d7f5d3SJohn Marino /* Allocate a new current chunk for the obstack *H
232*86d7f5d3SJohn Marino on the assumption that LENGTH bytes need to be added
233*86d7f5d3SJohn Marino to the current object, or a new object of length LENGTH allocated.
234*86d7f5d3SJohn Marino Copies any partial object from the end of the old chunk
235*86d7f5d3SJohn Marino to the beginning of the new one. */
236*86d7f5d3SJohn Marino
237*86d7f5d3SJohn Marino void
_obstack_newchunk(struct obstack * h,int length)238*86d7f5d3SJohn Marino _obstack_newchunk (struct obstack *h, int length)
239*86d7f5d3SJohn Marino {
240*86d7f5d3SJohn Marino register struct _obstack_chunk *old_chunk = h->chunk;
241*86d7f5d3SJohn Marino register struct _obstack_chunk *new_chunk;
242*86d7f5d3SJohn Marino register long new_size;
243*86d7f5d3SJohn Marino register long obj_size = h->next_free - h->object_base;
244*86d7f5d3SJohn Marino register long i;
245*86d7f5d3SJohn Marino long already;
246*86d7f5d3SJohn Marino
247*86d7f5d3SJohn Marino /* Compute size for new chunk. */
248*86d7f5d3SJohn Marino new_size = (obj_size + length) + (obj_size >> 3) + 100;
249*86d7f5d3SJohn Marino if (new_size < h->chunk_size)
250*86d7f5d3SJohn Marino new_size = h->chunk_size;
251*86d7f5d3SJohn Marino
252*86d7f5d3SJohn Marino /* Allocate and initialize the new chunk. */
253*86d7f5d3SJohn Marino new_chunk = CALL_CHUNKFUN (h, new_size);
254*86d7f5d3SJohn Marino if (!new_chunk)
255*86d7f5d3SJohn Marino (*obstack_alloc_failed_handler) ();
256*86d7f5d3SJohn Marino h->chunk = new_chunk;
257*86d7f5d3SJohn Marino new_chunk->prev = old_chunk;
258*86d7f5d3SJohn Marino new_chunk->limit = h->chunk_limit = (char *) new_chunk + new_size;
259*86d7f5d3SJohn Marino
260*86d7f5d3SJohn Marino /* Move the existing object to the new chunk.
261*86d7f5d3SJohn Marino Word at a time is fast and is safe if the object
262*86d7f5d3SJohn Marino is sufficiently aligned. */
263*86d7f5d3SJohn Marino if (h->alignment_mask + 1 >= DEFAULT_ALIGNMENT)
264*86d7f5d3SJohn Marino {
265*86d7f5d3SJohn Marino for (i = obj_size / sizeof (COPYING_UNIT) - 1;
266*86d7f5d3SJohn Marino i >= 0; i--)
267*86d7f5d3SJohn Marino ((COPYING_UNIT *)new_chunk->contents)[i]
268*86d7f5d3SJohn Marino = ((COPYING_UNIT *)h->object_base)[i];
269*86d7f5d3SJohn Marino /* We used to copy the odd few remaining bytes as one extra COPYING_UNIT,
270*86d7f5d3SJohn Marino but that can cross a page boundary on a machine
271*86d7f5d3SJohn Marino which does not do strict alignment for COPYING_UNITS. */
272*86d7f5d3SJohn Marino already = obj_size / sizeof (COPYING_UNIT) * sizeof (COPYING_UNIT);
273*86d7f5d3SJohn Marino }
274*86d7f5d3SJohn Marino else
275*86d7f5d3SJohn Marino already = 0;
276*86d7f5d3SJohn Marino /* Copy remaining bytes one by one. */
277*86d7f5d3SJohn Marino for (i = already; i < obj_size; i++)
278*86d7f5d3SJohn Marino new_chunk->contents[i] = h->object_base[i];
279*86d7f5d3SJohn Marino
280*86d7f5d3SJohn Marino /* If the object just copied was the only data in OLD_CHUNK,
281*86d7f5d3SJohn Marino free that chunk and remove it from the chain.
282*86d7f5d3SJohn Marino But not if that chunk might contain an empty object. */
283*86d7f5d3SJohn Marino if (h->object_base == old_chunk->contents && ! h->maybe_empty_object)
284*86d7f5d3SJohn Marino {
285*86d7f5d3SJohn Marino new_chunk->prev = old_chunk->prev;
286*86d7f5d3SJohn Marino CALL_FREEFUN (h, old_chunk);
287*86d7f5d3SJohn Marino }
288*86d7f5d3SJohn Marino
289*86d7f5d3SJohn Marino h->object_base = new_chunk->contents;
290*86d7f5d3SJohn Marino h->next_free = h->object_base + obj_size;
291*86d7f5d3SJohn Marino /* The new chunk certainly contains no empty object yet. */
292*86d7f5d3SJohn Marino h->maybe_empty_object = 0;
293*86d7f5d3SJohn Marino }
294*86d7f5d3SJohn Marino
295*86d7f5d3SJohn Marino /* Return nonzero if object OBJ has been allocated from obstack H.
296*86d7f5d3SJohn Marino This is here for debugging.
297*86d7f5d3SJohn Marino If you use it in a program, you are probably losing. */
298*86d7f5d3SJohn Marino
299*86d7f5d3SJohn Marino /* Suppress -Wmissing-prototypes warning. We don't want to declare this in
300*86d7f5d3SJohn Marino obstack.h because it is just for debugging. */
301*86d7f5d3SJohn Marino int _obstack_allocated_p (struct obstack *h, POINTER obj);
302*86d7f5d3SJohn Marino
303*86d7f5d3SJohn Marino int
_obstack_allocated_p(struct obstack * h,POINTER obj)304*86d7f5d3SJohn Marino _obstack_allocated_p (struct obstack *h, POINTER obj)
305*86d7f5d3SJohn Marino {
306*86d7f5d3SJohn Marino register struct _obstack_chunk *lp; /* below addr of any objects in this chunk */
307*86d7f5d3SJohn Marino register struct _obstack_chunk *plp; /* point to previous chunk if any */
308*86d7f5d3SJohn Marino
309*86d7f5d3SJohn Marino lp = (h)->chunk;
310*86d7f5d3SJohn Marino /* We use >= rather than > since the object cannot be exactly at
311*86d7f5d3SJohn Marino the beginning of the chunk but might be an empty object exactly
312*86d7f5d3SJohn Marino at the end of an adjacent chunk. */
313*86d7f5d3SJohn Marino while (lp != 0 && ((POINTER) lp >= obj || (POINTER) (lp)->limit < obj))
314*86d7f5d3SJohn Marino {
315*86d7f5d3SJohn Marino plp = lp->prev;
316*86d7f5d3SJohn Marino lp = plp;
317*86d7f5d3SJohn Marino }
318*86d7f5d3SJohn Marino return lp != 0;
319*86d7f5d3SJohn Marino }
320*86d7f5d3SJohn Marino
321*86d7f5d3SJohn Marino /* Free objects in obstack H, including OBJ and everything allocate
322*86d7f5d3SJohn Marino more recently than OBJ. If OBJ is zero, free everything in H. */
323*86d7f5d3SJohn Marino
324*86d7f5d3SJohn Marino #undef obstack_free
325*86d7f5d3SJohn Marino
326*86d7f5d3SJohn Marino /* This function has two names with identical definitions.
327*86d7f5d3SJohn Marino This is the first one, called from non-ANSI code. */
328*86d7f5d3SJohn Marino
329*86d7f5d3SJohn Marino void
_obstack_free(struct obstack * h,POINTER obj)330*86d7f5d3SJohn Marino _obstack_free (struct obstack *h, POINTER obj)
331*86d7f5d3SJohn Marino {
332*86d7f5d3SJohn Marino register struct _obstack_chunk *lp; /* below addr of any objects in this chunk */
333*86d7f5d3SJohn Marino register struct _obstack_chunk *plp; /* point to previous chunk if any */
334*86d7f5d3SJohn Marino
335*86d7f5d3SJohn Marino lp = h->chunk;
336*86d7f5d3SJohn Marino /* We use >= because there cannot be an object at the beginning of a chunk.
337*86d7f5d3SJohn Marino But there can be an empty object at that address
338*86d7f5d3SJohn Marino at the end of another chunk. */
339*86d7f5d3SJohn Marino while (lp != 0 && ((POINTER) lp >= obj || (POINTER) (lp)->limit < obj))
340*86d7f5d3SJohn Marino {
341*86d7f5d3SJohn Marino plp = lp->prev;
342*86d7f5d3SJohn Marino CALL_FREEFUN (h, lp);
343*86d7f5d3SJohn Marino lp = plp;
344*86d7f5d3SJohn Marino /* If we switch chunks, we can't tell whether the new current
345*86d7f5d3SJohn Marino chunk contains an empty object, so assume that it may. */
346*86d7f5d3SJohn Marino h->maybe_empty_object = 1;
347*86d7f5d3SJohn Marino }
348*86d7f5d3SJohn Marino if (lp)
349*86d7f5d3SJohn Marino {
350*86d7f5d3SJohn Marino h->object_base = h->next_free = (char *) (obj);
351*86d7f5d3SJohn Marino h->chunk_limit = lp->limit;
352*86d7f5d3SJohn Marino h->chunk = lp;
353*86d7f5d3SJohn Marino }
354*86d7f5d3SJohn Marino else if (obj != 0)
355*86d7f5d3SJohn Marino /* obj is not in any of the chunks! */
356*86d7f5d3SJohn Marino abort ();
357*86d7f5d3SJohn Marino }
358*86d7f5d3SJohn Marino
359*86d7f5d3SJohn Marino /* This function is used from ANSI code. */
360*86d7f5d3SJohn Marino
361*86d7f5d3SJohn Marino void
obstack_free(struct obstack * h,POINTER obj)362*86d7f5d3SJohn Marino obstack_free (struct obstack *h, POINTER obj)
363*86d7f5d3SJohn Marino {
364*86d7f5d3SJohn Marino register struct _obstack_chunk *lp; /* below addr of any objects in this chunk */
365*86d7f5d3SJohn Marino register struct _obstack_chunk *plp; /* point to previous chunk if any */
366*86d7f5d3SJohn Marino
367*86d7f5d3SJohn Marino lp = h->chunk;
368*86d7f5d3SJohn Marino /* We use >= because there cannot be an object at the beginning of a chunk.
369*86d7f5d3SJohn Marino But there can be an empty object at that address
370*86d7f5d3SJohn Marino at the end of another chunk. */
371*86d7f5d3SJohn Marino while (lp != 0 && ((POINTER) lp >= obj || (POINTER) (lp)->limit < obj))
372*86d7f5d3SJohn Marino {
373*86d7f5d3SJohn Marino plp = lp->prev;
374*86d7f5d3SJohn Marino CALL_FREEFUN (h, lp);
375*86d7f5d3SJohn Marino lp = plp;
376*86d7f5d3SJohn Marino /* If we switch chunks, we can't tell whether the new current
377*86d7f5d3SJohn Marino chunk contains an empty object, so assume that it may. */
378*86d7f5d3SJohn Marino h->maybe_empty_object = 1;
379*86d7f5d3SJohn Marino }
380*86d7f5d3SJohn Marino if (lp)
381*86d7f5d3SJohn Marino {
382*86d7f5d3SJohn Marino h->object_base = h->next_free = (char *) (obj);
383*86d7f5d3SJohn Marino h->chunk_limit = lp->limit;
384*86d7f5d3SJohn Marino h->chunk = lp;
385*86d7f5d3SJohn Marino }
386*86d7f5d3SJohn Marino else if (obj != 0)
387*86d7f5d3SJohn Marino /* obj is not in any of the chunks! */
388*86d7f5d3SJohn Marino abort ();
389*86d7f5d3SJohn Marino }
390*86d7f5d3SJohn Marino
391*86d7f5d3SJohn Marino int
_obstack_memory_used(struct obstack * h)392*86d7f5d3SJohn Marino _obstack_memory_used (struct obstack *h)
393*86d7f5d3SJohn Marino {
394*86d7f5d3SJohn Marino register struct _obstack_chunk* lp;
395*86d7f5d3SJohn Marino register int nbytes = 0;
396*86d7f5d3SJohn Marino
397*86d7f5d3SJohn Marino for (lp = h->chunk; lp != 0; lp = lp->prev)
398*86d7f5d3SJohn Marino {
399*86d7f5d3SJohn Marino nbytes += lp->limit - (char *) lp;
400*86d7f5d3SJohn Marino }
401*86d7f5d3SJohn Marino return nbytes;
402*86d7f5d3SJohn Marino }
403*86d7f5d3SJohn Marino
404*86d7f5d3SJohn Marino /* Define the error handler. */
405*86d7f5d3SJohn Marino #ifndef _
406*86d7f5d3SJohn Marino # if (HAVE_LIBINTL_H && ENABLE_NLS) || defined _LIBC
407*86d7f5d3SJohn Marino # include <libintl.h>
408*86d7f5d3SJohn Marino # ifndef _
409*86d7f5d3SJohn Marino # define _(Str) gettext (Str)
410*86d7f5d3SJohn Marino # endif
411*86d7f5d3SJohn Marino # else
412*86d7f5d3SJohn Marino # define _(Str) (Str)
413*86d7f5d3SJohn Marino # endif
414*86d7f5d3SJohn Marino #endif
415*86d7f5d3SJohn Marino
416*86d7f5d3SJohn Marino static void
print_and_abort(void)417*86d7f5d3SJohn Marino print_and_abort (void)
418*86d7f5d3SJohn Marino {
419*86d7f5d3SJohn Marino fputs (_("memory exhausted\n"), stderr);
420*86d7f5d3SJohn Marino exit (obstack_exit_failure);
421*86d7f5d3SJohn Marino }
422*86d7f5d3SJohn Marino
423*86d7f5d3SJohn Marino #if 0
424*86d7f5d3SJohn Marino /* These are now turned off because the applications do not use it
425*86d7f5d3SJohn Marino and it uses bcopy via obstack_grow, which causes trouble on sysV. */
426*86d7f5d3SJohn Marino
427*86d7f5d3SJohn Marino /* Now define the functional versions of the obstack macros.
428*86d7f5d3SJohn Marino Define them to simply use the corresponding macros to do the job. */
429*86d7f5d3SJohn Marino
430*86d7f5d3SJohn Marino /* The function names appear in parentheses in order to prevent
431*86d7f5d3SJohn Marino the macro-definitions of the names from being expanded there. */
432*86d7f5d3SJohn Marino
433*86d7f5d3SJohn Marino POINTER (obstack_base) (struct obstack *obstack)
434*86d7f5d3SJohn Marino {
435*86d7f5d3SJohn Marino return obstack_base (obstack);
436*86d7f5d3SJohn Marino }
437*86d7f5d3SJohn Marino
438*86d7f5d3SJohn Marino POINTER (obstack_next_free) (struct obstack *obstack)
439*86d7f5d3SJohn Marino {
440*86d7f5d3SJohn Marino return obstack_next_free (obstack);
441*86d7f5d3SJohn Marino }
442*86d7f5d3SJohn Marino
443*86d7f5d3SJohn Marino int (obstack_object_size) (struct obstack *obstack)
444*86d7f5d3SJohn Marino {
445*86d7f5d3SJohn Marino return obstack_object_size (obstack);
446*86d7f5d3SJohn Marino }
447*86d7f5d3SJohn Marino
448*86d7f5d3SJohn Marino int (obstack_room) (struct obstack *obstack)
449*86d7f5d3SJohn Marino {
450*86d7f5d3SJohn Marino return obstack_room (obstack);
451*86d7f5d3SJohn Marino }
452*86d7f5d3SJohn Marino
453*86d7f5d3SJohn Marino int (obstack_make_room) (struct obstack *obstack, int length)
454*86d7f5d3SJohn Marino {
455*86d7f5d3SJohn Marino return obstack_make_room (obstack, length);
456*86d7f5d3SJohn Marino }
457*86d7f5d3SJohn Marino
458*86d7f5d3SJohn Marino void (obstack_grow) (struct obstack *obstack, POINTER pointer, int length)
459*86d7f5d3SJohn Marino {
460*86d7f5d3SJohn Marino obstack_grow (obstack, pointer, length);
461*86d7f5d3SJohn Marino }
462*86d7f5d3SJohn Marino
463*86d7f5d3SJohn Marino void (obstack_grow0) (struct obstack *obstack, POINTER pointer, int length)
464*86d7f5d3SJohn Marino {
465*86d7f5d3SJohn Marino obstack_grow0 (obstack, pointer, length);
466*86d7f5d3SJohn Marino }
467*86d7f5d3SJohn Marino
468*86d7f5d3SJohn Marino void (obstack_1grow) (struct obstack *obstack, int character)
469*86d7f5d3SJohn Marino {
470*86d7f5d3SJohn Marino obstack_1grow (obstack, character);
471*86d7f5d3SJohn Marino }
472*86d7f5d3SJohn Marino
473*86d7f5d3SJohn Marino void (obstack_blank) (struct obstack *obstack, int length)
474*86d7f5d3SJohn Marino {
475*86d7f5d3SJohn Marino obstack_blank (obstack, length);
476*86d7f5d3SJohn Marino }
477*86d7f5d3SJohn Marino
478*86d7f5d3SJohn Marino void (obstack_1grow_fast) (struct obstack *obstack, int character)
479*86d7f5d3SJohn Marino {
480*86d7f5d3SJohn Marino obstack_1grow_fast (obstack, character);
481*86d7f5d3SJohn Marino }
482*86d7f5d3SJohn Marino
483*86d7f5d3SJohn Marino void (obstack_blank_fast) (struct obstack *obstack, int length)
484*86d7f5d3SJohn Marino {
485*86d7f5d3SJohn Marino obstack_blank_fast (obstack, length);
486*86d7f5d3SJohn Marino }
487*86d7f5d3SJohn Marino
488*86d7f5d3SJohn Marino POINTER (obstack_finish) (struct obstack *obstack)
489*86d7f5d3SJohn Marino {
490*86d7f5d3SJohn Marino return obstack_finish (obstack);
491*86d7f5d3SJohn Marino }
492*86d7f5d3SJohn Marino
493*86d7f5d3SJohn Marino POINTER (obstack_alloc) (struct obstack *obstack, int length)
494*86d7f5d3SJohn Marino {
495*86d7f5d3SJohn Marino return obstack_alloc (obstack, length);
496*86d7f5d3SJohn Marino }
497*86d7f5d3SJohn Marino
498*86d7f5d3SJohn Marino POINTER (obstack_copy) (struct obstack *obstack, POINTER pointer, int length)
499*86d7f5d3SJohn Marino {
500*86d7f5d3SJohn Marino return obstack_copy (obstack, pointer, length);
501*86d7f5d3SJohn Marino }
502*86d7f5d3SJohn Marino
503*86d7f5d3SJohn Marino POINTER (obstack_copy0) (struct obstack *obstack, POINTER pointer, int length)
504*86d7f5d3SJohn Marino {
505*86d7f5d3SJohn Marino return obstack_copy0 (obstack, pointer, length);
506*86d7f5d3SJohn Marino }
507*86d7f5d3SJohn Marino
508*86d7f5d3SJohn Marino #endif /* 0 */
509*86d7f5d3SJohn Marino
510*86d7f5d3SJohn Marino #endif /* !ELIDE_CODE */
511