xref: /openbsd-src/gnu/lib/libiberty/src/obstack.c (revision 20fce977aadac3358da45d5027d7d19cdc03b0fe)
100bf4279Sespie /* obstack.c - subroutines used implicitly by object stack macros
200bf4279Sespie    Copyright (C) 1988,89,90,91,92,93,94,96,97 Free Software Foundation, Inc.
300bf4279Sespie 
400bf4279Sespie 
52e0724c7Sespie    NOTE: This source is derived from an old version taken from the GNU C
62e0724c7Sespie    Library (glibc).
700bf4279Sespie 
800bf4279Sespie    This program is free software; you can redistribute it and/or modify it
900bf4279Sespie    under the terms of the GNU General Public License as published by the
1000bf4279Sespie    Free Software Foundation; either version 2, or (at your option) any
1100bf4279Sespie    later version.
1200bf4279Sespie 
1300bf4279Sespie    This program is distributed in the hope that it will be useful,
1400bf4279Sespie    but WITHOUT ANY WARRANTY; without even the implied warranty of
1500bf4279Sespie    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1600bf4279Sespie    GNU General Public License for more details.
1700bf4279Sespie 
1800bf4279Sespie    You should have received a copy of the GNU General Public License
1900bf4279Sespie    along with this program; if not, write to the Free Software
20*20fce977Smiod    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301,
2100bf4279Sespie    USA.  */
2200bf4279Sespie 
2300bf4279Sespie #ifdef HAVE_CONFIG_H
2400bf4279Sespie #include <config.h>
2500bf4279Sespie #endif
2600bf4279Sespie 
2700bf4279Sespie #include "obstack.h"
2800bf4279Sespie 
2900bf4279Sespie /* NOTE BEFORE MODIFYING THIS FILE: This version number must be
3000bf4279Sespie    incremented whenever callers compiled using an old obstack.h can no
3100bf4279Sespie    longer properly call the functions in this obstack.c.  */
3200bf4279Sespie #define OBSTACK_INTERFACE_VERSION 1
3300bf4279Sespie 
3400bf4279Sespie /* Comment out all this code if we are using the GNU C Library, and are not
3500bf4279Sespie    actually compiling the library itself, and the installed library
3600bf4279Sespie    supports the same library interface we do.  This code is part of the GNU
3700bf4279Sespie    C Library, but also included in many other GNU distributions.  Compiling
3800bf4279Sespie    and linking in this code is a waste when using the GNU C library
3900bf4279Sespie    (especially if it is a shared library).  Rather than having every GNU
4000bf4279Sespie    program understand `configure --with-gnu-libc' and omit the object
4100bf4279Sespie    files, it is simpler to just do this in the source for each such file.  */
4200bf4279Sespie 
4300bf4279Sespie #include <stdio.h>		/* Random thing to get __GNU_LIBRARY__.  */
4400bf4279Sespie #if !defined (_LIBC) && defined (__GNU_LIBRARY__) && __GNU_LIBRARY__ > 1
4500bf4279Sespie #include <gnu-versions.h>
4600bf4279Sespie #if _GNU_OBSTACK_INTERFACE_VERSION == OBSTACK_INTERFACE_VERSION
4700bf4279Sespie #define ELIDE_CODE
4800bf4279Sespie #endif
4900bf4279Sespie #endif
5000bf4279Sespie 
5100bf4279Sespie 
5200bf4279Sespie #ifndef ELIDE_CODE
5300bf4279Sespie 
5400bf4279Sespie 
5500bf4279Sespie #define POINTER void *
5600bf4279Sespie 
5700bf4279Sespie /* Determine default alignment.  */
5800bf4279Sespie struct fooalign {char x; double d;};
5900bf4279Sespie #define DEFAULT_ALIGNMENT  \
6000bf4279Sespie   ((PTR_INT_TYPE) ((char *) &((struct fooalign *) 0)->d - (char *) 0))
6100bf4279Sespie /* If malloc were really smart, it would round addresses to DEFAULT_ALIGNMENT.
6200bf4279Sespie    But in fact it might be less smart and round addresses to as much as
6300bf4279Sespie    DEFAULT_ROUNDING.  So we prepare for it to do that.  */
6400bf4279Sespie union fooround {long x; double d;};
6500bf4279Sespie #define DEFAULT_ROUNDING (sizeof (union fooround))
6600bf4279Sespie 
6700bf4279Sespie /* When we copy a long block of data, this is the unit to do it with.
6800bf4279Sespie    On some machines, copying successive ints does not work;
6900bf4279Sespie    in such a case, redefine COPYING_UNIT to `long' (if that works)
7000bf4279Sespie    or `char' as a last resort.  */
7100bf4279Sespie #ifndef COPYING_UNIT
7200bf4279Sespie #define COPYING_UNIT int
7300bf4279Sespie #endif
7400bf4279Sespie 
7500bf4279Sespie 
7600bf4279Sespie /* The functions allocating more room by calling `obstack_chunk_alloc'
7700bf4279Sespie    jump to the handler pointed to by `obstack_alloc_failed_handler'.
7800bf4279Sespie    This variable by default points to the internal function
7900bf4279Sespie    `print_and_abort'.  */
8000bf4279Sespie static void print_and_abort (void);
8100bf4279Sespie void (*obstack_alloc_failed_handler) (void) = print_and_abort;
8200bf4279Sespie 
8300bf4279Sespie /* Exit value used when `print_and_abort' is used.  */
8400bf4279Sespie #if defined __GNU_LIBRARY__ || defined HAVE_STDLIB_H
8500bf4279Sespie #include <stdlib.h>
8600bf4279Sespie #endif
8700bf4279Sespie #ifndef EXIT_FAILURE
8800bf4279Sespie #define EXIT_FAILURE 1
8900bf4279Sespie #endif
9000bf4279Sespie int obstack_exit_failure = EXIT_FAILURE;
9100bf4279Sespie 
9200bf4279Sespie /* The non-GNU-C macros copy the obstack into this global variable
9300bf4279Sespie    to avoid multiple evaluation.  */
9400bf4279Sespie 
9500bf4279Sespie struct obstack *_obstack;
9600bf4279Sespie 
9700bf4279Sespie /* Define a macro that either calls functions with the traditional malloc/free
9800bf4279Sespie    calling interface, or calls functions with the mmalloc/mfree interface
9900bf4279Sespie    (that adds an extra first argument), based on the state of use_extra_arg.
10000bf4279Sespie    For free, do not use ?:, since some compilers, like the MIPS compilers,
10100bf4279Sespie    do not allow (expr) ? void : void.  */
10200bf4279Sespie 
10300bf4279Sespie #if defined (__STDC__) && __STDC__
10400bf4279Sespie #define CALL_CHUNKFUN(h, size) \
10500bf4279Sespie   (((h) -> use_extra_arg) \
10600bf4279Sespie    ? (*(h)->chunkfun) ((h)->extra_arg, (size)) \
10700bf4279Sespie    : (*(struct _obstack_chunk *(*) (long)) (h)->chunkfun) ((size)))
10800bf4279Sespie 
10900bf4279Sespie #define CALL_FREEFUN(h, old_chunk) \
11000bf4279Sespie   do { \
11100bf4279Sespie     if ((h) -> use_extra_arg) \
11200bf4279Sespie       (*(h)->freefun) ((h)->extra_arg, (old_chunk)); \
11300bf4279Sespie     else \
11400bf4279Sespie       (*(void (*) (void *)) (h)->freefun) ((old_chunk)); \
11500bf4279Sespie   } while (0)
11600bf4279Sespie #else
11700bf4279Sespie #define CALL_CHUNKFUN(h, size) \
11800bf4279Sespie   (((h) -> use_extra_arg) \
11900bf4279Sespie    ? (*(h)->chunkfun) ((h)->extra_arg, (size)) \
12000bf4279Sespie    : (*(struct _obstack_chunk *(*) ()) (h)->chunkfun) ((size)))
12100bf4279Sespie 
12200bf4279Sespie #define CALL_FREEFUN(h, old_chunk) \
12300bf4279Sespie   do { \
12400bf4279Sespie     if ((h) -> use_extra_arg) \
12500bf4279Sespie       (*(h)->freefun) ((h)->extra_arg, (old_chunk)); \
12600bf4279Sespie     else \
12700bf4279Sespie       (*(void (*) ()) (h)->freefun) ((old_chunk)); \
12800bf4279Sespie   } while (0)
12900bf4279Sespie #endif
13000bf4279Sespie 
13100bf4279Sespie 
13200bf4279Sespie /* Initialize an obstack H for use.  Specify chunk size SIZE (0 means default).
13300bf4279Sespie    Objects start on multiples of ALIGNMENT (0 means use default).
13400bf4279Sespie    CHUNKFUN is the function to use to allocate chunks,
13500bf4279Sespie    and FREEFUN the function to free them.
13600bf4279Sespie 
13700bf4279Sespie    Return nonzero if successful, zero if out of memory.
13800bf4279Sespie    To recover from an out of memory error,
13900bf4279Sespie    free up some memory, then call this again.  */
14000bf4279Sespie 
14100bf4279Sespie int
_obstack_begin(struct obstack * h,int size,int alignment,POINTER (* chunkfun)(long),void (* freefun)(void *))142*20fce977Smiod _obstack_begin (struct obstack *h, int size, int alignment,
143*20fce977Smiod                 POINTER (*chunkfun) (long), void (*freefun) (void *))
14400bf4279Sespie {
14500bf4279Sespie   register struct _obstack_chunk *chunk; /* points to new chunk */
14600bf4279Sespie 
14700bf4279Sespie   if (alignment == 0)
14800bf4279Sespie     alignment = (int) DEFAULT_ALIGNMENT;
14900bf4279Sespie   if (size == 0)
15000bf4279Sespie     /* Default size is what GNU malloc can fit in a 4096-byte block.  */
15100bf4279Sespie     {
15200bf4279Sespie       /* 12 is sizeof (mhead) and 4 is EXTRA from GNU malloc.
15300bf4279Sespie 	 Use the values for range checking, because if range checking is off,
15400bf4279Sespie 	 the extra bytes won't be missed terribly, but if range checking is on
15500bf4279Sespie 	 and we used a larger request, a whole extra 4096 bytes would be
15600bf4279Sespie 	 allocated.
15700bf4279Sespie 
15800bf4279Sespie 	 These number are irrelevant to the new GNU malloc.  I suspect it is
15900bf4279Sespie 	 less sensitive to the size of the request.  */
16000bf4279Sespie       int extra = ((((12 + DEFAULT_ROUNDING - 1) & ~(DEFAULT_ROUNDING - 1))
16100bf4279Sespie 		    + 4 + DEFAULT_ROUNDING - 1)
16200bf4279Sespie 		   & ~(DEFAULT_ROUNDING - 1));
16300bf4279Sespie       size = 4096 - extra;
16400bf4279Sespie     }
16500bf4279Sespie 
16600bf4279Sespie   h->chunkfun = (struct _obstack_chunk * (*)(void *, long)) chunkfun;
16700bf4279Sespie   h->freefun = (void (*) (void *, struct _obstack_chunk *)) freefun;
16800bf4279Sespie   h->chunk_size = size;
16900bf4279Sespie   h->alignment_mask = alignment - 1;
17000bf4279Sespie   h->use_extra_arg = 0;
17100bf4279Sespie 
17200bf4279Sespie   chunk = h->chunk = CALL_CHUNKFUN (h, h -> chunk_size);
17300bf4279Sespie   if (!chunk)
17400bf4279Sespie     (*obstack_alloc_failed_handler) ();
17500bf4279Sespie   h->next_free = h->object_base = chunk->contents;
17600bf4279Sespie   h->chunk_limit = chunk->limit
17700bf4279Sespie     = (char *) chunk + h->chunk_size;
17800bf4279Sespie   chunk->prev = 0;
17900bf4279Sespie   /* The initial chunk now contains no empty object.  */
18000bf4279Sespie   h->maybe_empty_object = 0;
18100bf4279Sespie   h->alloc_failed = 0;
18200bf4279Sespie   return 1;
18300bf4279Sespie }
18400bf4279Sespie 
18500bf4279Sespie int
_obstack_begin_1(struct obstack * h,int size,int alignment,POINTER (* chunkfun)(POINTER,long),void (* freefun)(POINTER,POINTER),POINTER arg)186*20fce977Smiod _obstack_begin_1 (struct obstack *h, int size, int alignment,
187*20fce977Smiod                   POINTER (*chunkfun) (POINTER, long),
188*20fce977Smiod                   void (*freefun) (POINTER, POINTER), POINTER arg)
18900bf4279Sespie {
19000bf4279Sespie   register struct _obstack_chunk *chunk; /* points to new chunk */
19100bf4279Sespie 
19200bf4279Sespie   if (alignment == 0)
19300bf4279Sespie     alignment = (int) DEFAULT_ALIGNMENT;
19400bf4279Sespie   if (size == 0)
19500bf4279Sespie     /* Default size is what GNU malloc can fit in a 4096-byte block.  */
19600bf4279Sespie     {
19700bf4279Sespie       /* 12 is sizeof (mhead) and 4 is EXTRA from GNU malloc.
19800bf4279Sespie 	 Use the values for range checking, because if range checking is off,
19900bf4279Sespie 	 the extra bytes won't be missed terribly, but if range checking is on
20000bf4279Sespie 	 and we used a larger request, a whole extra 4096 bytes would be
20100bf4279Sespie 	 allocated.
20200bf4279Sespie 
20300bf4279Sespie 	 These number are irrelevant to the new GNU malloc.  I suspect it is
20400bf4279Sespie 	 less sensitive to the size of the request.  */
20500bf4279Sespie       int extra = ((((12 + DEFAULT_ROUNDING - 1) & ~(DEFAULT_ROUNDING - 1))
20600bf4279Sespie 		    + 4 + DEFAULT_ROUNDING - 1)
20700bf4279Sespie 		   & ~(DEFAULT_ROUNDING - 1));
20800bf4279Sespie       size = 4096 - extra;
20900bf4279Sespie     }
21000bf4279Sespie 
21100bf4279Sespie   h->chunkfun = (struct _obstack_chunk * (*)(void *,long)) chunkfun;
21200bf4279Sespie   h->freefun = (void (*) (void *, struct _obstack_chunk *)) freefun;
21300bf4279Sespie   h->chunk_size = size;
21400bf4279Sespie   h->alignment_mask = alignment - 1;
21500bf4279Sespie   h->extra_arg = arg;
21600bf4279Sespie   h->use_extra_arg = 1;
21700bf4279Sespie 
21800bf4279Sespie   chunk = h->chunk = CALL_CHUNKFUN (h, h -> chunk_size);
21900bf4279Sespie   if (!chunk)
22000bf4279Sespie     (*obstack_alloc_failed_handler) ();
22100bf4279Sespie   h->next_free = h->object_base = chunk->contents;
22200bf4279Sespie   h->chunk_limit = chunk->limit
22300bf4279Sespie     = (char *) chunk + h->chunk_size;
22400bf4279Sespie   chunk->prev = 0;
22500bf4279Sespie   /* The initial chunk now contains no empty object.  */
22600bf4279Sespie   h->maybe_empty_object = 0;
22700bf4279Sespie   h->alloc_failed = 0;
22800bf4279Sespie   return 1;
22900bf4279Sespie }
23000bf4279Sespie 
23100bf4279Sespie /* Allocate a new current chunk for the obstack *H
23200bf4279Sespie    on the assumption that LENGTH bytes need to be added
23300bf4279Sespie    to the current object, or a new object of length LENGTH allocated.
23400bf4279Sespie    Copies any partial object from the end of the old chunk
23500bf4279Sespie    to the beginning of the new one.  */
23600bf4279Sespie 
23700bf4279Sespie void
_obstack_newchunk(struct obstack * h,int length)238*20fce977Smiod _obstack_newchunk (struct obstack *h, int length)
23900bf4279Sespie {
24000bf4279Sespie   register struct _obstack_chunk *old_chunk = h->chunk;
24100bf4279Sespie   register struct _obstack_chunk *new_chunk;
24200bf4279Sespie   register long	new_size;
24300bf4279Sespie   register long obj_size = h->next_free - h->object_base;
24400bf4279Sespie   register long i;
24500bf4279Sespie   long already;
24600bf4279Sespie 
24700bf4279Sespie   /* Compute size for new chunk.  */
24800bf4279Sespie   new_size = (obj_size + length) + (obj_size >> 3) + 100;
24900bf4279Sespie   if (new_size < h->chunk_size)
25000bf4279Sespie     new_size = h->chunk_size;
25100bf4279Sespie 
25200bf4279Sespie   /* Allocate and initialize the new chunk.  */
25300bf4279Sespie   new_chunk = CALL_CHUNKFUN (h, new_size);
25400bf4279Sespie   if (!new_chunk)
25500bf4279Sespie     (*obstack_alloc_failed_handler) ();
25600bf4279Sespie   h->chunk = new_chunk;
25700bf4279Sespie   new_chunk->prev = old_chunk;
25800bf4279Sespie   new_chunk->limit = h->chunk_limit = (char *) new_chunk + new_size;
25900bf4279Sespie 
26000bf4279Sespie   /* Move the existing object to the new chunk.
26100bf4279Sespie      Word at a time is fast and is safe if the object
26200bf4279Sespie      is sufficiently aligned.  */
26300bf4279Sespie   if (h->alignment_mask + 1 >= DEFAULT_ALIGNMENT)
26400bf4279Sespie     {
26500bf4279Sespie       for (i = obj_size / sizeof (COPYING_UNIT) - 1;
26600bf4279Sespie 	   i >= 0; i--)
26700bf4279Sespie 	((COPYING_UNIT *)new_chunk->contents)[i]
26800bf4279Sespie 	  = ((COPYING_UNIT *)h->object_base)[i];
26900bf4279Sespie       /* We used to copy the odd few remaining bytes as one extra COPYING_UNIT,
27000bf4279Sespie 	 but that can cross a page boundary on a machine
27100bf4279Sespie 	 which does not do strict alignment for COPYING_UNITS.  */
27200bf4279Sespie       already = obj_size / sizeof (COPYING_UNIT) * sizeof (COPYING_UNIT);
27300bf4279Sespie     }
27400bf4279Sespie   else
27500bf4279Sespie     already = 0;
27600bf4279Sespie   /* Copy remaining bytes one by one.  */
27700bf4279Sespie   for (i = already; i < obj_size; i++)
27800bf4279Sespie     new_chunk->contents[i] = h->object_base[i];
27900bf4279Sespie 
28000bf4279Sespie   /* If the object just copied was the only data in OLD_CHUNK,
28100bf4279Sespie      free that chunk and remove it from the chain.
28200bf4279Sespie      But not if that chunk might contain an empty object.  */
28300bf4279Sespie   if (h->object_base == old_chunk->contents && ! h->maybe_empty_object)
28400bf4279Sespie     {
28500bf4279Sespie       new_chunk->prev = old_chunk->prev;
28600bf4279Sespie       CALL_FREEFUN (h, old_chunk);
28700bf4279Sespie     }
28800bf4279Sespie 
28900bf4279Sespie   h->object_base = new_chunk->contents;
29000bf4279Sespie   h->next_free = h->object_base + obj_size;
29100bf4279Sespie   /* The new chunk certainly contains no empty object yet.  */
29200bf4279Sespie   h->maybe_empty_object = 0;
29300bf4279Sespie }
29400bf4279Sespie 
29500bf4279Sespie /* Return nonzero if object OBJ has been allocated from obstack H.
29600bf4279Sespie    This is here for debugging.
29700bf4279Sespie    If you use it in a program, you are probably losing.  */
29800bf4279Sespie 
29900bf4279Sespie /* Suppress -Wmissing-prototypes warning.  We don't want to declare this in
30000bf4279Sespie    obstack.h because it is just for debugging.  */
30100bf4279Sespie int _obstack_allocated_p (struct obstack *h, POINTER obj);
30200bf4279Sespie 
30300bf4279Sespie int
_obstack_allocated_p(struct obstack * h,POINTER obj)304*20fce977Smiod _obstack_allocated_p (struct obstack *h, POINTER obj)
30500bf4279Sespie {
30600bf4279Sespie   register struct _obstack_chunk *lp;	/* below addr of any objects in this chunk */
30700bf4279Sespie   register struct _obstack_chunk *plp;	/* point to previous chunk if any */
30800bf4279Sespie 
30900bf4279Sespie   lp = (h)->chunk;
31000bf4279Sespie   /* We use >= rather than > since the object cannot be exactly at
31100bf4279Sespie      the beginning of the chunk but might be an empty object exactly
31200bf4279Sespie      at the end of an adjacent chunk.  */
31300bf4279Sespie   while (lp != 0 && ((POINTER) lp >= obj || (POINTER) (lp)->limit < obj))
31400bf4279Sespie     {
31500bf4279Sespie       plp = lp->prev;
31600bf4279Sespie       lp = plp;
31700bf4279Sespie     }
31800bf4279Sespie   return lp != 0;
31900bf4279Sespie }
32000bf4279Sespie 
32100bf4279Sespie /* Free objects in obstack H, including OBJ and everything allocate
32200bf4279Sespie    more recently than OBJ.  If OBJ is zero, free everything in H.  */
32300bf4279Sespie 
32400bf4279Sespie #undef obstack_free
32500bf4279Sespie 
32600bf4279Sespie /* This function has two names with identical definitions.
32700bf4279Sespie    This is the first one, called from non-ANSI code.  */
32800bf4279Sespie 
32900bf4279Sespie void
_obstack_free(struct obstack * h,POINTER obj)330*20fce977Smiod _obstack_free (struct obstack *h, POINTER obj)
33100bf4279Sespie {
33200bf4279Sespie   register struct _obstack_chunk *lp;	/* below addr of any objects in this chunk */
33300bf4279Sespie   register struct _obstack_chunk *plp;	/* point to previous chunk if any */
33400bf4279Sespie 
33500bf4279Sespie   lp = h->chunk;
33600bf4279Sespie   /* We use >= because there cannot be an object at the beginning of a chunk.
33700bf4279Sespie      But there can be an empty object at that address
33800bf4279Sespie      at the end of another chunk.  */
33900bf4279Sespie   while (lp != 0 && ((POINTER) lp >= obj || (POINTER) (lp)->limit < obj))
34000bf4279Sespie     {
34100bf4279Sespie       plp = lp->prev;
34200bf4279Sespie       CALL_FREEFUN (h, lp);
34300bf4279Sespie       lp = plp;
34400bf4279Sespie       /* If we switch chunks, we can't tell whether the new current
34500bf4279Sespie 	 chunk contains an empty object, so assume that it may.  */
34600bf4279Sespie       h->maybe_empty_object = 1;
34700bf4279Sespie     }
34800bf4279Sespie   if (lp)
34900bf4279Sespie     {
35000bf4279Sespie       h->object_base = h->next_free = (char *) (obj);
35100bf4279Sespie       h->chunk_limit = lp->limit;
35200bf4279Sespie       h->chunk = lp;
35300bf4279Sespie     }
35400bf4279Sespie   else if (obj != 0)
35500bf4279Sespie     /* obj is not in any of the chunks! */
35600bf4279Sespie     abort ();
35700bf4279Sespie }
35800bf4279Sespie 
35900bf4279Sespie /* This function is used from ANSI code.  */
36000bf4279Sespie 
36100bf4279Sespie void
obstack_free(struct obstack * h,POINTER obj)362*20fce977Smiod obstack_free (struct obstack *h, POINTER obj)
36300bf4279Sespie {
36400bf4279Sespie   register struct _obstack_chunk *lp;	/* below addr of any objects in this chunk */
36500bf4279Sespie   register struct _obstack_chunk *plp;	/* point to previous chunk if any */
36600bf4279Sespie 
36700bf4279Sespie   lp = h->chunk;
36800bf4279Sespie   /* We use >= because there cannot be an object at the beginning of a chunk.
36900bf4279Sespie      But there can be an empty object at that address
37000bf4279Sespie      at the end of another chunk.  */
37100bf4279Sespie   while (lp != 0 && ((POINTER) lp >= obj || (POINTER) (lp)->limit < obj))
37200bf4279Sespie     {
37300bf4279Sespie       plp = lp->prev;
37400bf4279Sespie       CALL_FREEFUN (h, lp);
37500bf4279Sespie       lp = plp;
37600bf4279Sespie       /* If we switch chunks, we can't tell whether the new current
37700bf4279Sespie 	 chunk contains an empty object, so assume that it may.  */
37800bf4279Sespie       h->maybe_empty_object = 1;
37900bf4279Sespie     }
38000bf4279Sespie   if (lp)
38100bf4279Sespie     {
38200bf4279Sespie       h->object_base = h->next_free = (char *) (obj);
38300bf4279Sespie       h->chunk_limit = lp->limit;
38400bf4279Sespie       h->chunk = lp;
38500bf4279Sespie     }
38600bf4279Sespie   else if (obj != 0)
38700bf4279Sespie     /* obj is not in any of the chunks! */
38800bf4279Sespie     abort ();
38900bf4279Sespie }
39000bf4279Sespie 
39100bf4279Sespie int
_obstack_memory_used(struct obstack * h)392*20fce977Smiod _obstack_memory_used (struct obstack *h)
39300bf4279Sespie {
39400bf4279Sespie   register struct _obstack_chunk* lp;
39500bf4279Sespie   register int nbytes = 0;
39600bf4279Sespie 
39700bf4279Sespie   for (lp = h->chunk; lp != 0; lp = lp->prev)
39800bf4279Sespie     {
39900bf4279Sespie       nbytes += lp->limit - (char *) lp;
40000bf4279Sespie     }
40100bf4279Sespie   return nbytes;
40200bf4279Sespie }
40300bf4279Sespie 
40400bf4279Sespie /* Define the error handler.  */
40500bf4279Sespie #ifndef _
4069588ddcfSespie # if (HAVE_LIBINTL_H && ENABLE_NLS) || defined _LIBC
40700bf4279Sespie #  include <libintl.h>
40800bf4279Sespie #  ifndef _
40900bf4279Sespie #   define _(Str) gettext (Str)
41000bf4279Sespie #  endif
41100bf4279Sespie # else
41200bf4279Sespie #  define _(Str) (Str)
41300bf4279Sespie # endif
41400bf4279Sespie #endif
41500bf4279Sespie 
41600bf4279Sespie static void
print_and_abort(void)417*20fce977Smiod print_and_abort (void)
41800bf4279Sespie {
41900bf4279Sespie   fputs (_("memory exhausted\n"), stderr);
42000bf4279Sespie   exit (obstack_exit_failure);
42100bf4279Sespie }
42200bf4279Sespie 
42300bf4279Sespie #if 0
42400bf4279Sespie /* These are now turned off because the applications do not use it
42500bf4279Sespie    and it uses bcopy via obstack_grow, which causes trouble on sysV.  */
42600bf4279Sespie 
42700bf4279Sespie /* Now define the functional versions of the obstack macros.
42800bf4279Sespie    Define them to simply use the corresponding macros to do the job.  */
42900bf4279Sespie 
43000bf4279Sespie /* The function names appear in parentheses in order to prevent
43100bf4279Sespie    the macro-definitions of the names from being expanded there.  */
43200bf4279Sespie 
433*20fce977Smiod POINTER (obstack_base) (struct obstack *obstack)
43400bf4279Sespie {
43500bf4279Sespie   return obstack_base (obstack);
43600bf4279Sespie }
43700bf4279Sespie 
438*20fce977Smiod POINTER (obstack_next_free) (struct obstack *obstack)
43900bf4279Sespie {
44000bf4279Sespie   return obstack_next_free (obstack);
44100bf4279Sespie }
44200bf4279Sespie 
443*20fce977Smiod int (obstack_object_size) (struct obstack *obstack)
44400bf4279Sespie {
44500bf4279Sespie   return obstack_object_size (obstack);
44600bf4279Sespie }
44700bf4279Sespie 
448*20fce977Smiod int (obstack_room) (struct obstack *obstack)
44900bf4279Sespie {
45000bf4279Sespie   return obstack_room (obstack);
45100bf4279Sespie }
45200bf4279Sespie 
453*20fce977Smiod int (obstack_make_room) (struct obstack *obstack, int length)
45400bf4279Sespie {
45500bf4279Sespie   return obstack_make_room (obstack, length);
45600bf4279Sespie }
45700bf4279Sespie 
458*20fce977Smiod void (obstack_grow) (struct obstack *obstack, POINTER pointer, int length)
45900bf4279Sespie {
46000bf4279Sespie   obstack_grow (obstack, pointer, length);
46100bf4279Sespie }
46200bf4279Sespie 
463*20fce977Smiod void (obstack_grow0) (struct obstack *obstack, POINTER pointer, int length)
46400bf4279Sespie {
46500bf4279Sespie   obstack_grow0 (obstack, pointer, length);
46600bf4279Sespie }
46700bf4279Sespie 
468*20fce977Smiod void (obstack_1grow) (struct obstack *obstack, int character)
46900bf4279Sespie {
47000bf4279Sespie   obstack_1grow (obstack, character);
47100bf4279Sespie }
47200bf4279Sespie 
473*20fce977Smiod void (obstack_blank) (struct obstack *obstack, int length)
47400bf4279Sespie {
47500bf4279Sespie   obstack_blank (obstack, length);
47600bf4279Sespie }
47700bf4279Sespie 
478*20fce977Smiod void (obstack_1grow_fast) (struct obstack *obstack, int character)
47900bf4279Sespie {
48000bf4279Sespie   obstack_1grow_fast (obstack, character);
48100bf4279Sespie }
48200bf4279Sespie 
483*20fce977Smiod void (obstack_blank_fast) (struct obstack *obstack, int length)
48400bf4279Sespie {
48500bf4279Sespie   obstack_blank_fast (obstack, length);
48600bf4279Sespie }
48700bf4279Sespie 
488*20fce977Smiod POINTER (obstack_finish) (struct obstack *obstack)
48900bf4279Sespie {
49000bf4279Sespie   return obstack_finish (obstack);
49100bf4279Sespie }
49200bf4279Sespie 
493*20fce977Smiod POINTER (obstack_alloc) (struct obstack *obstack, int length)
49400bf4279Sespie {
49500bf4279Sespie   return obstack_alloc (obstack, length);
49600bf4279Sespie }
49700bf4279Sespie 
498*20fce977Smiod POINTER (obstack_copy) (struct obstack *obstack, POINTER pointer, int length)
49900bf4279Sespie {
50000bf4279Sespie   return obstack_copy (obstack, pointer, length);
50100bf4279Sespie }
50200bf4279Sespie 
503*20fce977Smiod POINTER (obstack_copy0) (struct obstack *obstack, POINTER pointer, int length)
50400bf4279Sespie {
50500bf4279Sespie   return obstack_copy0 (obstack, pointer, length);
50600bf4279Sespie }
50700bf4279Sespie 
50800bf4279Sespie #endif /* 0 */
50900bf4279Sespie 
51000bf4279Sespie #endif	/* !ELIDE_CODE */
511