xref: /dflybsd-src/contrib/gdb-7/libiberty/obstack.c (revision 86d7f5d305c6adaa56ff4582ece9859d73106103)
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