(root)/
tar-1.35/
gnu/
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     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  /* This file uses _Noreturn, _GL_ATTRIBUTE_PURE.  */
     107  #if !_GL_CONFIG_H_INCLUDED
     108   #error "Please include config.h first."
     109  #endif
     110  
     111  #ifndef _OBSTACK_INTERFACE_VERSION
     112  # define _OBSTACK_INTERFACE_VERSION 2
     113  #endif
     114  
     115  #include <stddef.h>             /* For size_t and ptrdiff_t.  */
     116  #include <string.h>             /* For __GNU_LIBRARY__, and memcpy.  */
     117  
     118  #if __STDC_VERSION__ < 199901L || defined __HP_cc
     119  # define __FLEXIBLE_ARRAY_MEMBER 1
     120  #else
     121  # define __FLEXIBLE_ARRAY_MEMBER
     122  #endif
     123  
     124  #if _OBSTACK_INTERFACE_VERSION == 1
     125  /* For binary compatibility with obstack version 1, which used "int"
     126     and "long" for these two types.  */
     127  # define _OBSTACK_SIZE_T unsigned int
     128  # define _CHUNK_SIZE_T unsigned long
     129  # define _OBSTACK_CAST(type, expr) ((type) (expr))
     130  #else
     131  /* Version 2 with sane types, especially for 64-bit hosts.  */
     132  # define _OBSTACK_SIZE_T size_t
     133  # define _CHUNK_SIZE_T size_t
     134  # define _OBSTACK_CAST(type, expr) (expr)
     135  #endif
     136  
     137  /* If B is the base of an object addressed by P, return the result of
     138     aligning P to the next multiple of A + 1.  B and P must be of type
     139     char *.  A + 1 must be a power of 2.  */
     140  
     141  #define __BPTR_ALIGN(B, P, A) ((B) + (((P) - (B) + (A)) & ~(A)))
     142  
     143  /* Similar to __BPTR_ALIGN (B, P, A), except optimize the common case
     144     where pointers can be converted to integers, aligned as integers,
     145     and converted back again.  If ptrdiff_t is narrower than a
     146     pointer (e.g., the AS/400), play it safe and compute the alignment
     147     relative to B.  Otherwise, use the faster strategy of computing the
     148     alignment relative to 0.  */
     149  
     150  #define __PTR_ALIGN(B, P, A)						      \
     151    __BPTR_ALIGN (sizeof (ptrdiff_t) < sizeof (void *) ? (B) : (char *) 0,      \
     152                  P, A)
     153  
     154  #ifndef __attribute_pure__
     155  # define __attribute_pure__ _GL_ATTRIBUTE_PURE
     156  #endif
     157  
     158  /* Not the same as _Noreturn, since it also works with function pointers.  */
     159  #ifndef __attribute_noreturn__
     160  # if 2 < __GNUC__ + (8 <= __GNUC_MINOR__) || defined __clang__ || 0x5110 <= __SUNPRO_C
     161  #  define __attribute_noreturn__ __attribute__ ((__noreturn__))
     162  # else
     163  #  define __attribute_noreturn__
     164  # endif
     165  #endif
     166  
     167  #ifdef __cplusplus
     168  extern "C" {
     169  #endif
     170  
     171  struct _obstack_chunk           /* Lives at front of each chunk. */
     172  {
     173    char *limit;                  /* 1 past end of this chunk */
     174    struct _obstack_chunk *prev;  /* address of prior chunk or NULL */
     175    char contents[__FLEXIBLE_ARRAY_MEMBER]; /* objects begin here */
     176  };
     177  
     178  struct obstack          /* control current object in current chunk */
     179  {
     180    _CHUNK_SIZE_T chunk_size;     /* preferred size to allocate chunks in */
     181    struct _obstack_chunk *chunk; /* address of current struct obstack_chunk */
     182    char *object_base;            /* address of object we are building */
     183    char *next_free;              /* where to add next char to current object */
     184    char *chunk_limit;            /* address of char after current chunk */
     185    union
     186    {
     187      _OBSTACK_SIZE_T i;
     188      void *p;
     189    } temp;                       /* Temporary for some macros.  */
     190    _OBSTACK_SIZE_T alignment_mask;  /* Mask of alignment for each object. */
     191  
     192    /* These prototypes vary based on 'use_extra_arg'.  */
     193    union
     194    {
     195      void *(*plain) (size_t);
     196      void *(*extra) (void *, size_t);
     197    } chunkfun;
     198    union
     199    {
     200      void (*plain) (void *);
     201      void (*extra) (void *, void *);
     202    } freefun;
     203  
     204    void *extra_arg;              /* first arg for chunk alloc/dealloc funcs */
     205    unsigned use_extra_arg : 1;     /* chunk alloc/dealloc funcs take extra arg */
     206    unsigned maybe_empty_object : 1; /* There is a possibility that the current
     207                                        chunk contains a zero-length object.  This
     208                                        prevents freeing the chunk if we allocate
     209                                        a bigger chunk to replace it. */
     210    unsigned alloc_failed : 1;      /* No longer used, as we now call the failed
     211                                       handler on error, but retained for binary
     212                                       compatibility.  */
     213  };
     214  
     215  /* Declare the external functions we use; they are in obstack.c.  */
     216  
     217  extern void _obstack_newchunk (struct obstack *, _OBSTACK_SIZE_T);
     218  extern void _obstack_free (struct obstack *, void *);
     219  extern int _obstack_begin (struct obstack *,
     220                             _OBSTACK_SIZE_T, _OBSTACK_SIZE_T,
     221                             void *(*) (size_t), void (*) (void *));
     222  extern int _obstack_begin_1 (struct obstack *,
     223                               _OBSTACK_SIZE_T, _OBSTACK_SIZE_T,
     224                               void *(*) (void *, size_t),
     225                               void (*) (void *, void *), void *);
     226  extern _OBSTACK_SIZE_T _obstack_memory_used (struct obstack *)
     227    __attribute_pure__;
     228  
     229  
     230  /* Error handler called when 'obstack_chunk_alloc' failed to allocate
     231     more memory.  This can be set to a user defined function which
     232     should either abort gracefully or use longjump - but shouldn't
     233     return.  The default action is to print a message and abort.  */
     234  extern __attribute_noreturn__ void (*obstack_alloc_failed_handler) (void);
     235  
     236  /* Exit value used when 'print_and_abort' is used.  */
     237  extern int obstack_exit_failure;
     238  
     239  /* Pointer to beginning of object being allocated or to be allocated next.
     240     Note that this might not be the final address of the object
     241     because a new chunk might be needed to hold the final size.  */
     242  
     243  #define obstack_base(h) ((void *) (h)->object_base)
     244  
     245  /* Size for allocating ordinary chunks.  */
     246  
     247  #define obstack_chunk_size(h) ((h)->chunk_size)
     248  
     249  /* Pointer to next byte not yet allocated in current chunk.  */
     250  
     251  #define obstack_next_free(h) ((void *) (h)->next_free)
     252  
     253  /* Mask specifying low bits that should be clear in address of an object.  */
     254  
     255  #define obstack_alignment_mask(h) ((h)->alignment_mask)
     256  
     257  /* To prevent prototype warnings provide complete argument list.  */
     258  #define obstack_init(h)							      \
     259    _obstack_begin ((h), 0, 0,						      \
     260                    _OBSTACK_CAST (void *(*) (size_t), obstack_chunk_alloc),    \
     261                    _OBSTACK_CAST (void (*) (void *), obstack_chunk_free))
     262  
     263  #define obstack_begin(h, size)						      \
     264    _obstack_begin ((h), (size), 0,					      \
     265                    _OBSTACK_CAST (void *(*) (size_t), obstack_chunk_alloc), \
     266                    _OBSTACK_CAST (void (*) (void *), obstack_chunk_free))
     267  
     268  #define obstack_specify_allocation(h, size, alignment, chunkfun, freefun)     \
     269    _obstack_begin ((h), (size), (alignment),				      \
     270                    _OBSTACK_CAST (void *(*) (size_t), chunkfun),		      \
     271                    _OBSTACK_CAST (void (*) (void *), freefun))
     272  
     273  #define obstack_specify_allocation_with_arg(h, size, alignment, chunkfun, freefun, arg) \
     274    _obstack_begin_1 ((h), (size), (alignment),				      \
     275                      _OBSTACK_CAST (void *(*) (void *, size_t), chunkfun),     \
     276                      _OBSTACK_CAST (void (*) (void *, void *), freefun), arg)
     277  
     278  #define obstack_chunkfun(h, newchunkfun)				      \
     279    ((void) ((h)->chunkfun.extra = (void *(*) (void *, size_t)) (newchunkfun)))
     280  
     281  #define obstack_freefun(h, newfreefun)					      \
     282    ((void) ((h)->freefun.extra = (void *(*) (void *, void *)) (newfreefun)))
     283  
     284  #define obstack_1grow_fast(h, achar) ((void) (*((h)->next_free)++ = (achar)))
     285  
     286  #define obstack_blank_fast(h, n) ((void) ((h)->next_free += (n)))
     287  
     288  #define obstack_memory_used(h) _obstack_memory_used (h)
     289  
     290  #if defined __GNUC__ || defined __clang__
     291  # if !(defined __GNUC_MINOR__ && __GNUC__ * 1000 + __GNUC_MINOR__ >= 2008 \
     292         || defined __clang__)
     293  #  define __extension__
     294  # endif
     295  
     296  /* For GNU C, if not -traditional,
     297     we can define these macros to compute all args only once
     298     without using a global variable.
     299     Also, we can avoid using the 'temp' slot, to make faster code.  */
     300  
     301  # define obstack_object_size(OBSTACK)					      \
     302    __extension__								      \
     303      ({ struct obstack const *__o = (OBSTACK);				      \
     304         (_OBSTACK_SIZE_T) (__o->next_free - __o->object_base); })
     305  
     306  /* The local variable is named __o1 to avoid a shadowed variable
     307     warning when invoked from other obstack macros.  */
     308  # define obstack_room(OBSTACK)						      \
     309    __extension__								      \
     310      ({ struct obstack const *__o1 = (OBSTACK);				      \
     311         (_OBSTACK_SIZE_T) (__o1->chunk_limit - __o1->next_free); })
     312  
     313  # define obstack_make_room(OBSTACK, 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         (void) 0; })
     320  
     321  # define obstack_empty_p(OBSTACK)					      \
     322    __extension__								      \
     323      ({ struct obstack const *__o = (OBSTACK);				      \
     324         (__o->chunk->prev == 0						      \
     325          && __o->next_free == __PTR_ALIGN ((char *) __o->chunk,		      \
     326                                            __o->chunk->contents,		      \
     327                                            __o->alignment_mask)); })
     328  
     329  # define obstack_grow(OBSTACK, where, length)				      \
     330    __extension__								      \
     331      ({ struct obstack *__o = (OBSTACK);					      \
     332         _OBSTACK_SIZE_T __len = (length);				      \
     333         if (obstack_room (__o) < __len)					      \
     334           _obstack_newchunk (__o, __len);				      \
     335         memcpy (__o->next_free, where, __len);				      \
     336         __o->next_free += __len;						      \
     337         (void) 0; })
     338  
     339  # define obstack_grow0(OBSTACK, where, length)				      \
     340    __extension__								      \
     341      ({ struct obstack *__o = (OBSTACK);					      \
     342         _OBSTACK_SIZE_T __len = (length);				      \
     343         if (obstack_room (__o) < __len + 1)				      \
     344           _obstack_newchunk (__o, __len + 1);				      \
     345         memcpy (__o->next_free, where, __len);				      \
     346         __o->next_free += __len;						      \
     347         *(__o->next_free)++ = 0;						      \
     348         (void) 0; })
     349  
     350  # define obstack_1grow(OBSTACK, datum)					      \
     351    __extension__								      \
     352      ({ struct obstack *__o = (OBSTACK);					      \
     353         if (obstack_room (__o) < 1)					      \
     354           _obstack_newchunk (__o, 1);					      \
     355         obstack_1grow_fast (__o, datum); })
     356  
     357  /* These assume that the obstack alignment is good enough for pointers
     358     or ints, and that the data added so far to the current object
     359     shares that much alignment.  */
     360  
     361  # define obstack_ptr_grow(OBSTACK, datum)				      \
     362    __extension__								      \
     363      ({ struct obstack *__o = (OBSTACK);					      \
     364         if (obstack_room (__o) < sizeof (void *))			      \
     365           _obstack_newchunk (__o, sizeof (void *));			      \
     366         obstack_ptr_grow_fast (__o, datum); })
     367  
     368  # define obstack_int_grow(OBSTACK, datum)				      \
     369    __extension__								      \
     370      ({ struct obstack *__o = (OBSTACK);					      \
     371         if (obstack_room (__o) < sizeof (int))				      \
     372           _obstack_newchunk (__o, sizeof (int));				      \
     373         obstack_int_grow_fast (__o, datum); })
     374  
     375  # define obstack_ptr_grow_fast(OBSTACK, aptr)				      \
     376    __extension__								      \
     377      ({ struct obstack *__o1 = (OBSTACK);				      \
     378         void *__p1 = __o1->next_free;					      \
     379         *(const void **) __p1 = (aptr);					      \
     380         __o1->next_free += sizeof (const void *);			      \
     381         (void) 0; })
     382  
     383  # define obstack_int_grow_fast(OBSTACK, aint)				      \
     384    __extension__								      \
     385      ({ struct obstack *__o1 = (OBSTACK);				      \
     386         void *__p1 = __o1->next_free;					      \
     387         *(int *) __p1 = (aint);						      \
     388         __o1->next_free += sizeof (int);					      \
     389         (void) 0; })
     390  
     391  # define obstack_blank(OBSTACK, length)					      \
     392    __extension__								      \
     393      ({ struct obstack *__o = (OBSTACK);					      \
     394         _OBSTACK_SIZE_T __len = (length);				      \
     395         if (obstack_room (__o) < __len)					      \
     396           _obstack_newchunk (__o, __len);				      \
     397         obstack_blank_fast (__o, __len); })
     398  
     399  # define obstack_alloc(OBSTACK, length)					      \
     400    __extension__								      \
     401      ({ struct obstack *__h = (OBSTACK);					      \
     402         obstack_blank (__h, (length));					      \
     403         obstack_finish (__h); })
     404  
     405  # define obstack_copy(OBSTACK, where, length)				      \
     406    __extension__								      \
     407      ({ struct obstack *__h = (OBSTACK);					      \
     408         obstack_grow (__h, (where), (length));				      \
     409         obstack_finish (__h); })
     410  
     411  # define obstack_copy0(OBSTACK, where, length)				      \
     412    __extension__								      \
     413      ({ struct obstack *__h = (OBSTACK);					      \
     414         obstack_grow0 (__h, (where), (length));				      \
     415         obstack_finish (__h); })
     416  
     417  /* The local variable is named __o1 to avoid a shadowed variable
     418     warning when invoked from other obstack macros, typically obstack_free.  */
     419  # define obstack_finish(OBSTACK)					      \
     420    __extension__								      \
     421      ({ struct obstack *__o1 = (OBSTACK);				      \
     422         void *__value = (void *) __o1->object_base;			      \
     423         if (__o1->next_free == __value)					      \
     424           __o1->maybe_empty_object = 1;					      \
     425         __o1->next_free							      \
     426           = __PTR_ALIGN (__o1->object_base, __o1->next_free,		      \
     427                          __o1->alignment_mask);				      \
     428         if ((size_t) (__o1->next_free - (char *) __o1->chunk)		      \
     429             > (size_t) (__o1->chunk_limit - (char *) __o1->chunk))	      \
     430           __o1->next_free = __o1->chunk_limit;				      \
     431         __o1->object_base = __o1->next_free;				      \
     432         __value; })
     433  
     434  # define obstack_free(OBSTACK, OBJ)					      \
     435    __extension__								      \
     436      ({ struct obstack *__o = (OBSTACK);					      \
     437         void *__obj = (void *) (OBJ);					      \
     438         if (__obj > (void *) __o->chunk && __obj < (void *) __o->chunk_limit)  \
     439           __o->next_free = __o->object_base = (char *) __obj;		      \
     440         else								      \
     441           _obstack_free (__o, __obj); })
     442  
     443  #else /* not __GNUC__ */
     444  
     445  # define obstack_object_size(h)						      \
     446    ((_OBSTACK_SIZE_T) ((h)->next_free - (h)->object_base))
     447  
     448  # define obstack_room(h)						      \
     449    ((_OBSTACK_SIZE_T) ((h)->chunk_limit - (h)->next_free))
     450  
     451  # define obstack_empty_p(h)						      \
     452    ((h)->chunk->prev == 0						      \
     453     && (h)->next_free == __PTR_ALIGN ((char *) (h)->chunk,		      \
     454                                       (h)->chunk->contents,		      \
     455                                       (h)->alignment_mask))
     456  
     457  /* Note that the call to _obstack_newchunk is enclosed in (..., 0)
     458     so that we can avoid having void expressions
     459     in the arms of the conditional expression.
     460     Casting the third operand to void was tried before,
     461     but some compilers won't accept it.  */
     462  
     463  # define obstack_make_room(h, length)					      \
     464    ((h)->temp.i = (length),						      \
     465     ((obstack_room (h) < (h)->temp.i)					      \
     466      ? (_obstack_newchunk (h, (h)->temp.i), 0) : 0),			      \
     467     (void) 0)
     468  
     469  # define obstack_grow(h, where, length)					      \
     470    ((h)->temp.i = (length),						      \
     471     ((obstack_room (h) < (h)->temp.i)					      \
     472     ? (_obstack_newchunk ((h), (h)->temp.i), 0) : 0),			      \
     473     memcpy ((h)->next_free, where, (h)->temp.i),				      \
     474     (h)->next_free += (h)->temp.i,					      \
     475     (void) 0)
     476  
     477  # define obstack_grow0(h, where, length)				      \
     478    ((h)->temp.i = (length),						      \
     479     ((obstack_room (h) < (h)->temp.i + 1)				      \
     480     ? (_obstack_newchunk ((h), (h)->temp.i + 1), 0) : 0),		      \
     481     memcpy ((h)->next_free, where, (h)->temp.i),				      \
     482     (h)->next_free += (h)->temp.i,					      \
     483     *((h)->next_free)++ = 0,						      \
     484     (void) 0)
     485  
     486  # define obstack_1grow(h, datum)					      \
     487    (((obstack_room (h) < 1)						      \
     488      ? (_obstack_newchunk ((h), 1), 0) : 0),				      \
     489     obstack_1grow_fast (h, datum))
     490  
     491  # define obstack_ptr_grow(h, datum)					      \
     492    (((obstack_room (h) < sizeof (char *))				      \
     493      ? (_obstack_newchunk ((h), sizeof (char *)), 0) : 0),		      \
     494     obstack_ptr_grow_fast (h, datum))
     495  
     496  # define obstack_int_grow(h, datum)					      \
     497    (((obstack_room (h) < sizeof (int))					      \
     498      ? (_obstack_newchunk ((h), sizeof (int)), 0) : 0),			      \
     499     obstack_int_grow_fast (h, datum))
     500  
     501  # define obstack_ptr_grow_fast(h, aptr)					      \
     502    (((const void **) ((h)->next_free += sizeof (void *)))[-1] = (aptr),	      \
     503     (void) 0)
     504  
     505  # define obstack_int_grow_fast(h, aint)					      \
     506    (((int *) ((h)->next_free += sizeof (int)))[-1] = (aint),		      \
     507     (void) 0)
     508  
     509  # define obstack_blank(h, length)					      \
     510    ((h)->temp.i = (length),						      \
     511     ((obstack_room (h) < (h)->temp.i)					      \
     512     ? (_obstack_newchunk ((h), (h)->temp.i), 0) : 0),			      \
     513     obstack_blank_fast (h, (h)->temp.i))
     514  
     515  # define obstack_alloc(h, length)					      \
     516    (obstack_blank ((h), (length)), obstack_finish ((h)))
     517  
     518  # define obstack_copy(h, where, length)					      \
     519    (obstack_grow ((h), (where), (length)), obstack_finish ((h)))
     520  
     521  # define obstack_copy0(h, where, length)				      \
     522    (obstack_grow0 ((h), (where), (length)), obstack_finish ((h)))
     523  
     524  # define obstack_finish(h)						      \
     525    (((h)->next_free == (h)->object_base					      \
     526      ? (((h)->maybe_empty_object = 1), 0)				      \
     527      : 0),								      \
     528     (h)->temp.p = (h)->object_base,					      \
     529     (h)->next_free							      \
     530       = __PTR_ALIGN ((h)->object_base, (h)->next_free,			      \
     531                      (h)->alignment_mask),				      \
     532     (((size_t) ((h)->next_free - (char *) (h)->chunk)			      \
     533       > (size_t) ((h)->chunk_limit - (char *) (h)->chunk))		      \
     534     ? ((h)->next_free = (h)->chunk_limit) : 0),				      \
     535     (h)->object_base = (h)->next_free,					      \
     536     (h)->temp.p)
     537  
     538  # define obstack_free(h, obj)						      \
     539    ((h)->temp.p = (void *) (obj),					      \
     540     (((h)->temp.p > (void *) (h)->chunk					      \
     541       && (h)->temp.p < (void *) (h)->chunk_limit)			      \
     542      ? (void) ((h)->next_free = (h)->object_base = (char *) (h)->temp.p)       \
     543      : _obstack_free ((h), (h)->temp.p)))
     544  
     545  #endif /* not __GNUC__ */
     546  
     547  #ifdef __cplusplus
     548  }       /* C++ */
     549  #endif
     550  
     551  #endif /* _OBSTACK_H */