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