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