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