(root)/
gcc-13.2.0/
include/
obstack.h
       1  /* obstack.h - object stack macros
       2     Copyright (C) 1988-2023 Free Software Foundation, Inc.
       3     This file is part of the GNU C Library.
       4  
       5     The GNU C Library is free software; you can redistribute it and/or
       6     modify it under the terms of the GNU Lesser General Public
       7     License as published by the Free Software Foundation; either
       8     version 2.1 of the License, or (at your option) any later version.
       9  
      10     The GNU C Library is distributed in the hope that it will be useful,
      11     but WITHOUT ANY WARRANTY; without even the implied warranty of
      12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      13     Lesser General Public License for more details.
      14  
      15     You should have received a copy of the GNU Lesser General Public
      16     License along with the GNU C Library; if not, see
      17     <http://www.gnu.org/licenses/>.  */
      18  
      19  /* Summary:
      20  
      21     All the apparent functions defined here are macros. The idea
      22     is that you would use these pre-tested macros to solve a
      23     very specific set of problems, and they would run fast.
      24     Caution: no side-effects in arguments please!! They may be
      25     evaluated MANY times!!
      26  
      27     These macros operate a stack of objects.  Each object starts life
      28     small, and may grow to maturity.  (Consider building a word syllable
      29     by syllable.)  An object can move while it is growing.  Once it has
      30     been "finished" it never changes address again.  So the "top of the
      31     stack" is typically an immature growing object, while the rest of the
      32     stack is of mature, fixed size and fixed address objects.
      33  
      34     These routines grab large chunks of memory, using a function you
      35     supply, called 'obstack_chunk_alloc'.  On occasion, they free chunks,
      36     by calling 'obstack_chunk_free'.  You must define them and declare
      37     them before using any obstack macros.
      38  
      39     Each independent stack is represented by a 'struct obstack'.
      40     Each of the obstack macros expects a pointer to such a structure
      41     as the first argument.
      42  
      43     One motivation for this package is the problem of growing char strings
      44     in symbol tables.  Unless you are "fascist pig with a read-only mind"
      45     --Gosper's immortal quote from HAKMEM item 154, out of context--you
      46     would not like to put any arbitrary upper limit on the length of your
      47     symbols.
      48  
      49     In practice this often means you will build many short symbols and a
      50     few long symbols.  At the time you are reading a symbol you don't know
      51     how long it is.  One traditional method is to read a symbol into a
      52     buffer, realloc()ating the buffer every time you try to read a symbol
      53     that is longer than the buffer.  This is beaut, but you still will
      54     want to copy the symbol from the buffer to a more permanent
      55     symbol-table entry say about half the time.
      56  
      57     With obstacks, you can work differently.  Use one obstack for all symbol
      58     names.  As you read a symbol, grow the name in the obstack gradually.
      59     When the name is complete, finalize it.  Then, if the symbol exists already,
      60     free the newly read name.
      61  
      62     The way we do this is to take a large chunk, allocating memory from
      63     low addresses.  When you want to build a symbol in the chunk you just
      64     add chars above the current "high water mark" in the chunk.  When you
      65     have finished adding chars, because you got to the end of the symbol,
      66     you know how long the chars are, and you can create a new object.
      67     Mostly the chars will not burst over the highest address of the chunk,
      68     because you would typically expect a chunk to be (say) 100 times as
      69     long as an average object.
      70  
      71     In case that isn't clear, when we have enough chars to make up
      72     the object, THEY ARE ALREADY CONTIGUOUS IN THE CHUNK (guaranteed)
      73     so we just point to it where it lies.  No moving of chars is
      74     needed and this is the second win: potentially long strings need
      75     never be explicitly shuffled. Once an object is formed, it does not
      76     change its address during its lifetime.
      77  
      78     When the chars burst over a chunk boundary, we allocate a larger
      79     chunk, and then copy the partly formed object from the end of the old
      80     chunk to the beginning of the new larger chunk.  We then carry on
      81     accreting characters to the end of the object as we normally would.
      82  
      83     A special macro is provided to add a single char at a time to a
      84     growing object.  This allows the use of register variables, which
      85     break the ordinary 'growth' macro.
      86  
      87     Summary:
      88          We allocate large chunks.
      89          We carve out one object at a time from the current chunk.
      90          Once carved, an object never moves.
      91          We are free to append data of any size to the currently
      92            growing object.
      93          Exactly one object is growing in an obstack at any one time.
      94          You can run one obstack per control block.
      95          You may have as many control blocks as you dare.
      96          Because of the way we do it, you can "unwind" an obstack
      97            back to a previous state. (You may remove objects much
      98            as you would with a stack.)
      99   */
     100  
     101  
     102  /* Don't do the contents of this file more than once.  */
     103  
     104  #ifndef _OBSTACK_H
     105  #define _OBSTACK_H 1
     106  
     107  #ifndef _OBSTACK_INTERFACE_VERSION
     108  # define _OBSTACK_INTERFACE_VERSION 2
     109  #endif
     110  
     111  #include <stddef.h>             /* For size_t and ptrdiff_t.  */
     112  #include <string.h>             /* For __GNU_LIBRARY__, and memcpy.  */
     113  
     114  #if _OBSTACK_INTERFACE_VERSION == 1
     115  /* For binary compatibility with obstack version 1, which used "int"
     116     and "long" for these two types.  */
     117  # define _OBSTACK_SIZE_T unsigned int
     118  # define _CHUNK_SIZE_T unsigned long
     119  # define _OBSTACK_CAST(type, expr) ((type) (expr))
     120  #else
     121  /* Version 2 with sane types, especially for 64-bit hosts.  */
     122  # define _OBSTACK_SIZE_T size_t
     123  # define _CHUNK_SIZE_T size_t
     124  # define _OBSTACK_CAST(type, expr) (expr)
     125  #endif
     126  
     127  /* If B is the base of an object addressed by P, return the result of
     128     aligning P to the next multiple of A + 1.  B and P must be of type
     129     char *.  A + 1 must be a power of 2.  */
     130  
     131  #define __BPTR_ALIGN(B, P, A) ((B) + (((P) - (B) + (A)) & ~(A)))
     132  
     133  /* Similar to __BPTR_ALIGN (B, P, A), except optimize the common case
     134     where pointers can be converted to integers, aligned as integers,
     135     and converted back again.  If ptrdiff_t is narrower than a
     136     pointer (e.g., the AS/400), play it safe and compute the alignment
     137     relative to B.  Otherwise, use the faster strategy of computing the
     138     alignment relative to 0.  */
     139  
     140  #define __PTR_ALIGN(B, P, A)						\
     141    (sizeof (ptrdiff_t) < sizeof (void *) ? __BPTR_ALIGN (B, P, A)	\
     142     : (char *) (((ptrdiff_t) (P) + (A)) & ~(A)))
     143  
     144  #ifndef __attribute_pure__
     145  # if defined __GNUC_MINOR__ && __GNUC__ * 1000 + __GNUC_MINOR__ >= 2096
     146  #  define __attribute_pure__ __attribute__ ((__pure__))
     147  # else
     148  #  define __attribute_pure__
     149  # endif
     150  #endif
     151  
     152  #ifdef __cplusplus
     153  extern "C" {
     154  #endif
     155  
     156  struct _obstack_chunk           /* Lives at front of each chunk. */
     157  {
     158    char *limit;                  /* 1 past end of this chunk */
     159    struct _obstack_chunk *prev;  /* address of prior chunk or NULL */
     160    char contents[4];             /* objects begin here */
     161  };
     162  
     163  struct obstack          /* control current object in current chunk */
     164  {
     165    _CHUNK_SIZE_T chunk_size;     /* preferred size to allocate chunks in */
     166    struct _obstack_chunk *chunk; /* address of current struct obstack_chunk */
     167    char *object_base;            /* address of object we are building */
     168    char *next_free;              /* where to add next char to current object */
     169    char *chunk_limit;            /* address of char after current chunk */
     170    union
     171    {
     172      _OBSTACK_SIZE_T i;
     173      void *p;
     174    } temp;                       /* Temporary for some macros.  */
     175    _OBSTACK_SIZE_T alignment_mask;  /* Mask of alignment for each object. */
     176  
     177    /* These prototypes vary based on 'use_extra_arg'.  */
     178    union
     179    {
     180      void *(*plain) (size_t);
     181      void *(*extra) (void *, size_t);
     182    } chunkfun;
     183    union
     184    {
     185      void (*plain) (void *);
     186      void (*extra) (void *, void *);
     187    } freefun;
     188  
     189    void *extra_arg;              /* first arg for chunk alloc/dealloc funcs */
     190    unsigned use_extra_arg : 1;     /* chunk alloc/dealloc funcs take extra arg */
     191    unsigned maybe_empty_object : 1; /* There is a possibility that the current
     192                                        chunk contains a zero-length object.  This
     193                                        prevents freeing the chunk if we allocate
     194                                        a bigger chunk to replace it. */
     195    unsigned alloc_failed : 1;      /* No longer used, as we now call the failed
     196                                       handler on error, but retained for binary
     197                                       compatibility.  */
     198  };
     199  
     200  /* Declare the external functions we use; they are in obstack.c.  */
     201  
     202  extern void _obstack_newchunk (struct obstack *, _OBSTACK_SIZE_T);
     203  extern void _obstack_free (struct obstack *, void *);
     204  extern int _obstack_begin (struct obstack *,
     205                             _OBSTACK_SIZE_T, _OBSTACK_SIZE_T,
     206                             void *(*) (size_t), void (*) (void *));
     207  extern int _obstack_begin_1 (struct obstack *,
     208                               _OBSTACK_SIZE_T, _OBSTACK_SIZE_T,
     209                               void *(*) (void *, size_t),
     210                               void (*) (void *, void *), void *);
     211  extern _OBSTACK_SIZE_T _obstack_memory_used (struct obstack *)
     212    __attribute_pure__;
     213  
     214  
     215  /* Error handler called when 'obstack_chunk_alloc' failed to allocate
     216     more memory.  This can be set to a user defined function which
     217     should either abort gracefully or use longjump - but shouldn't
     218     return.  The default action is to print a message and abort.  */
     219  extern void (*obstack_alloc_failed_handler) (void);
     220  
     221  /* Exit value used when 'print_and_abort' is used.  */
     222  extern int obstack_exit_failure;
     223  
     224  /* Pointer to beginning of object being allocated or to be allocated next.
     225     Note that this might not be the final address of the object
     226     because a new chunk might be needed to hold the final size.  */
     227  
     228  #define obstack_base(h) ((void *) (h)->object_base)
     229  
     230  /* Size for allocating ordinary chunks.  */
     231  
     232  #define obstack_chunk_size(h) ((h)->chunk_size)
     233  
     234  /* Pointer to next byte not yet allocated in current chunk.  */
     235  
     236  #define obstack_next_free(h) ((void *) (h)->next_free)
     237  
     238  /* Mask specifying low bits that should be clear in address of an object.  */
     239  
     240  #define obstack_alignment_mask(h) ((h)->alignment_mask)
     241  
     242  /* To prevent prototype warnings provide complete argument list.  */
     243  #define obstack_init(h)							      \
     244    _obstack_begin ((h), 0, 0,						      \
     245                    _OBSTACK_CAST (void *(*) (size_t), obstack_chunk_alloc),    \
     246                    _OBSTACK_CAST (void (*) (void *), obstack_chunk_free))
     247  
     248  #define obstack_begin(h, size)						      \
     249    _obstack_begin ((h), (size), 0,					      \
     250                    _OBSTACK_CAST (void *(*) (size_t), obstack_chunk_alloc), \
     251                    _OBSTACK_CAST (void (*) (void *), obstack_chunk_free))
     252  
     253  #define obstack_specify_allocation(h, size, alignment, chunkfun, freefun)     \
     254    _obstack_begin ((h), (size), (alignment),				      \
     255                    _OBSTACK_CAST (void *(*) (size_t), chunkfun),		      \
     256                    _OBSTACK_CAST (void (*) (void *), freefun))
     257  
     258  #define obstack_specify_allocation_with_arg(h, size, alignment, chunkfun, freefun, arg) \
     259    _obstack_begin_1 ((h), (size), (alignment),				      \
     260                      _OBSTACK_CAST (void *(*) (void *, size_t), chunkfun),     \
     261                      _OBSTACK_CAST (void (*) (void *, void *), freefun), arg)
     262  
     263  #define obstack_chunkfun(h, newchunkfun)				      \
     264    ((void) ((h)->chunkfun.extra = (void *(*) (void *, size_t)) (newchunkfun)))
     265  
     266  #define obstack_freefun(h, newfreefun)					      \
     267    ((void) ((h)->freefun.extra = (void *(*) (void *, void *)) (newfreefun)))
     268  
     269  #define obstack_1grow_fast(h, achar) ((void) (*((h)->next_free)++ = (achar)))
     270  
     271  #define obstack_blank_fast(h, n) ((void) ((h)->next_free += (n)))
     272  
     273  #define obstack_memory_used(h) _obstack_memory_used (h)
     274  
     275  #if defined __GNUC__
     276  # if !defined __GNUC_MINOR__ || __GNUC__ * 1000 + __GNUC_MINOR__ < 2008
     277  #  define __extension__
     278  # endif
     279  
     280  /* For GNU C, if not -traditional,
     281     we can define these macros to compute all args only once
     282     without using a global variable.
     283     Also, we can avoid using the 'temp' slot, to make faster code.  */
     284  
     285  # define obstack_object_size(OBSTACK)					      \
     286    __extension__								      \
     287      ({ struct obstack const *__o = (OBSTACK);				      \
     288         (_OBSTACK_SIZE_T) (__o->next_free - __o->object_base); })
     289  
     290  /* The local variable is named __o1 to avoid a shadowed variable
     291     warning when invoked from other obstack macros.  */
     292  # define obstack_room(OBSTACK)						      \
     293    __extension__								      \
     294      ({ struct obstack const *__o1 = (OBSTACK);				      \
     295         (_OBSTACK_SIZE_T) (__o1->chunk_limit - __o1->next_free); })
     296  
     297  # define obstack_make_room(OBSTACK, length)				      \
     298    __extension__								      \
     299      ({ struct obstack *__o = (OBSTACK);					      \
     300         _OBSTACK_SIZE_T __len = (length);				      \
     301         if (obstack_room (__o) < __len)					      \
     302           _obstack_newchunk (__o, __len);				      \
     303         (void) 0; })
     304  
     305  # define obstack_empty_p(OBSTACK)					      \
     306    __extension__								      \
     307      ({ struct obstack const *__o = (OBSTACK);				      \
     308         (__o->chunk->prev == 0						      \
     309          && __o->next_free == __PTR_ALIGN ((char *) __o->chunk,		      \
     310                                            __o->chunk->contents,		      \
     311                                            __o->alignment_mask)); })
     312  
     313  # define obstack_grow(OBSTACK, where, length)				      \
     314    __extension__								      \
     315      ({ struct obstack *__o = (OBSTACK);					      \
     316         _OBSTACK_SIZE_T __len = (length);				      \
     317         if (obstack_room (__o) < __len)					      \
     318           _obstack_newchunk (__o, __len);				      \
     319         memcpy (__o->next_free, where, __len);				      \
     320         __o->next_free += __len;						      \
     321         (void) 0; })
     322  
     323  # define obstack_grow0(OBSTACK, where, length)				      \
     324    __extension__								      \
     325      ({ struct obstack *__o = (OBSTACK);					      \
     326         _OBSTACK_SIZE_T __len = (length);				      \
     327         if (obstack_room (__o) < __len + 1)				      \
     328           _obstack_newchunk (__o, __len + 1);				      \
     329         memcpy (__o->next_free, where, __len);				      \
     330         __o->next_free += __len;						      \
     331         *(__o->next_free)++ = 0;						      \
     332         (void) 0; })
     333  
     334  # define obstack_1grow(OBSTACK, datum)					      \
     335    __extension__								      \
     336      ({ struct obstack *__o = (OBSTACK);					      \
     337         if (obstack_room (__o) < 1)					      \
     338           _obstack_newchunk (__o, 1);					      \
     339         obstack_1grow_fast (__o, datum); })
     340  
     341  /* These assume that the obstack alignment is good enough for pointers
     342     or ints, and that the data added so far to the current object
     343     shares that much alignment.  */
     344  
     345  # define obstack_ptr_grow(OBSTACK, datum)				      \
     346    __extension__								      \
     347      ({ struct obstack *__o = (OBSTACK);					      \
     348         if (obstack_room (__o) < sizeof (void *))			      \
     349           _obstack_newchunk (__o, sizeof (void *));			      \
     350         obstack_ptr_grow_fast (__o, datum); })
     351  
     352  # define obstack_int_grow(OBSTACK, datum)				      \
     353    __extension__								      \
     354      ({ struct obstack *__o = (OBSTACK);					      \
     355         if (obstack_room (__o) < sizeof (int))				      \
     356           _obstack_newchunk (__o, sizeof (int));				      \
     357         obstack_int_grow_fast (__o, datum); })
     358  
     359  # define obstack_ptr_grow_fast(OBSTACK, aptr)				      \
     360    __extension__								      \
     361      ({ struct obstack *__o1 = (OBSTACK);				      \
     362         void *__p1 = __o1->next_free;					      \
     363         *(const void **) __p1 = (aptr);					      \
     364         __o1->next_free += sizeof (const void *);			      \
     365         (void) 0; })
     366  
     367  # define obstack_int_grow_fast(OBSTACK, aint)				      \
     368    __extension__								      \
     369      ({ struct obstack *__o1 = (OBSTACK);				      \
     370         void *__p1 = __o1->next_free;					      \
     371         *(int *) __p1 = (aint);						      \
     372         __o1->next_free += sizeof (int);					      \
     373         (void) 0; })
     374  
     375  # define obstack_blank(OBSTACK, length)					      \
     376    __extension__								      \
     377      ({ struct obstack *__o = (OBSTACK);					      \
     378         _OBSTACK_SIZE_T __len = (length);				      \
     379         if (obstack_room (__o) < __len)					      \
     380           _obstack_newchunk (__o, __len);				      \
     381         obstack_blank_fast (__o, __len); })
     382  
     383  # define obstack_alloc(OBSTACK, length)					      \
     384    __extension__								      \
     385      ({ struct obstack *__h = (OBSTACK);					      \
     386         obstack_blank (__h, (length));					      \
     387         obstack_finish (__h); })
     388  
     389  # define obstack_copy(OBSTACK, where, length)				      \
     390    __extension__								      \
     391      ({ struct obstack *__h = (OBSTACK);					      \
     392         obstack_grow (__h, (where), (length));				      \
     393         obstack_finish (__h); })
     394  
     395  # define obstack_copy0(OBSTACK, where, length)				      \
     396    __extension__								      \
     397      ({ struct obstack *__h = (OBSTACK);					      \
     398         obstack_grow0 (__h, (where), (length));				      \
     399         obstack_finish (__h); })
     400  
     401  /* The local variable is named __o1 to avoid a shadowed variable
     402     warning when invoked from other obstack macros, typically obstack_free.  */
     403  # define obstack_finish(OBSTACK)					      \
     404    __extension__								      \
     405      ({ struct obstack *__o1 = (OBSTACK);				      \
     406         void *__value = (void *) __o1->object_base;			      \
     407         if (__o1->next_free == __value)					      \
     408           __o1->maybe_empty_object = 1;					      \
     409         __o1->next_free							      \
     410           = __PTR_ALIGN (__o1->object_base, __o1->next_free,		      \
     411                          __o1->alignment_mask);				      \
     412         if ((size_t) (__o1->next_free - (char *) __o1->chunk)		      \
     413             > (size_t) (__o1->chunk_limit - (char *) __o1->chunk))	      \
     414           __o1->next_free = __o1->chunk_limit;				      \
     415         __o1->object_base = __o1->next_free;				      \
     416         __value; })
     417  
     418  # define obstack_free(OBSTACK, OBJ)					      \
     419    __extension__								      \
     420      ({ struct obstack *__o = (OBSTACK);					      \
     421         void *__obj = (void *) (OBJ);					      \
     422         if (__obj > (void *) __o->chunk && __obj < (void *) __o->chunk_limit)  \
     423           __o->next_free = __o->object_base = (char *) __obj;		      \
     424         else								      \
     425           _obstack_free (__o, __obj); })
     426  
     427  #else /* not __GNUC__ */
     428  
     429  # define obstack_object_size(h)						      \
     430    ((_OBSTACK_SIZE_T) ((h)->next_free - (h)->object_base))
     431  
     432  # define obstack_room(h)						      \
     433    ((_OBSTACK_SIZE_T) ((h)->chunk_limit - (h)->next_free))
     434  
     435  # define obstack_empty_p(h)						      \
     436    ((h)->chunk->prev == 0						      \
     437     && (h)->next_free == __PTR_ALIGN ((char *) (h)->chunk,		      \
     438                                       (h)->chunk->contents,		      \
     439                                       (h)->alignment_mask))
     440  
     441  /* Note that the call to _obstack_newchunk is enclosed in (..., 0)
     442     so that we can avoid having void expressions
     443     in the arms of the conditional expression.
     444     Casting the third operand to void was tried before,
     445     but some compilers won't accept it.  */
     446  
     447  # define obstack_make_room(h, length)					      \
     448    ((h)->temp.i = (length),						      \
     449     ((obstack_room (h) < (h)->temp.i)					      \
     450      ? (_obstack_newchunk (h, (h)->temp.i), 0) : 0),			      \
     451     (void) 0)
     452  
     453  # define obstack_grow(h, where, length)					      \
     454    ((h)->temp.i = (length),						      \
     455     ((obstack_room (h) < (h)->temp.i)					      \
     456     ? (_obstack_newchunk ((h), (h)->temp.i), 0) : 0),			      \
     457     memcpy ((h)->next_free, where, (h)->temp.i),				      \
     458     (h)->next_free += (h)->temp.i,					      \
     459     (void) 0)
     460  
     461  # define obstack_grow0(h, where, length)				      \
     462    ((h)->temp.i = (length),						      \
     463     ((obstack_room (h) < (h)->temp.i + 1)				      \
     464     ? (_obstack_newchunk ((h), (h)->temp.i + 1), 0) : 0),		      \
     465     memcpy ((h)->next_free, where, (h)->temp.i),				      \
     466     (h)->next_free += (h)->temp.i,					      \
     467     *((h)->next_free)++ = 0,						      \
     468     (void) 0)
     469  
     470  # define obstack_1grow(h, datum)					      \
     471    (((obstack_room (h) < 1)						      \
     472      ? (_obstack_newchunk ((h), 1), 0) : 0),				      \
     473     obstack_1grow_fast (h, datum))
     474  
     475  # define obstack_ptr_grow(h, datum)					      \
     476    (((obstack_room (h) < sizeof (char *))				      \
     477      ? (_obstack_newchunk ((h), sizeof (char *)), 0) : 0),		      \
     478     obstack_ptr_grow_fast (h, datum))
     479  
     480  # define obstack_int_grow(h, datum)					      \
     481    (((obstack_room (h) < sizeof (int))					      \
     482      ? (_obstack_newchunk ((h), sizeof (int)), 0) : 0),			      \
     483     obstack_int_grow_fast (h, datum))
     484  
     485  # define obstack_ptr_grow_fast(h, aptr)					      \
     486    (((const void **) ((h)->next_free += sizeof (void *)))[-1] = (aptr),	      \
     487     (void) 0)
     488  
     489  # define obstack_int_grow_fast(h, aint)					      \
     490    (((int *) ((h)->next_free += sizeof (int)))[-1] = (aint),		      \
     491     (void) 0)
     492  
     493  # define obstack_blank(h, length)					      \
     494    ((h)->temp.i = (length),						      \
     495     ((obstack_room (h) < (h)->temp.i)					      \
     496     ? (_obstack_newchunk ((h), (h)->temp.i), 0) : 0),			      \
     497     obstack_blank_fast (h, (h)->temp.i))
     498  
     499  # define obstack_alloc(h, length)					      \
     500    (obstack_blank ((h), (length)), obstack_finish ((h)))
     501  
     502  # define obstack_copy(h, where, length)					      \
     503    (obstack_grow ((h), (where), (length)), obstack_finish ((h)))
     504  
     505  # define obstack_copy0(h, where, length)				      \
     506    (obstack_grow0 ((h), (where), (length)), obstack_finish ((h)))
     507  
     508  # define obstack_finish(h)						      \
     509    (((h)->next_free == (h)->object_base					      \
     510      ? (((h)->maybe_empty_object = 1), 0)				      \
     511      : 0),								      \
     512     (h)->temp.p = (h)->object_base,					      \
     513     (h)->next_free							      \
     514       = __PTR_ALIGN ((h)->object_base, (h)->next_free,			      \
     515                      (h)->alignment_mask),				      \
     516     (((size_t) ((h)->next_free - (char *) (h)->chunk)			      \
     517       > (size_t) ((h)->chunk_limit - (char *) (h)->chunk))		      \
     518     ? ((h)->next_free = (h)->chunk_limit) : 0),				      \
     519     (h)->object_base = (h)->next_free,					      \
     520     (h)->temp.p)
     521  
     522  # define obstack_free(h, obj)						      \
     523    ((h)->temp.p = (void *) (obj),					      \
     524     (((h)->temp.p > (void *) (h)->chunk					      \
     525       && (h)->temp.p < (void *) (h)->chunk_limit)			      \
     526      ? (void) ((h)->next_free = (h)->object_base = (char *) (h)->temp.p)       \
     527      : _obstack_free ((h), (h)->temp.p)))
     528  
     529  #endif /* not __GNUC__ */
     530  
     531  #ifdef __cplusplus
     532  }       /* C++ */
     533  #endif
     534  
     535  #endif /* _OBSTACK_H */