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