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