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