Blame lib/obstack.h

Packit 709fb3
/* obstack.h - object stack macros
Packit 709fb3
   Copyright (C) 1988-2017 Free Software Foundation, Inc.
Packit 709fb3
   This file is part of the GNU C Library.
Packit 709fb3
Packit 709fb3
   The GNU C Library is free software; you can redistribute it and/or
Packit 709fb3
   modify it under the terms of the GNU General Public
Packit 709fb3
   License as published by the Free Software Foundation; either
Packit 709fb3
   version 3 of the License, or (at your option) any later version.
Packit 709fb3
Packit 709fb3
   The GNU C Library is distributed in the hope that it will be useful,
Packit 709fb3
   but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit 709fb3
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit 709fb3
   General Public License for more details.
Packit 709fb3
Packit 709fb3
   You should have received a copy of the GNU General Public
Packit 709fb3
   License along with the GNU C Library; if not, see
Packit 709fb3
   <http://www.gnu.org/licenses/>.  */
Packit 709fb3
Packit 709fb3
/* Summary:
Packit 709fb3
Packit 709fb3
   All the apparent functions defined here are macros. The idea
Packit 709fb3
   is that you would use these pre-tested macros to solve a
Packit 709fb3
   very specific set of problems, and they would run fast.
Packit 709fb3
   Caution: no side-effects in arguments please!! They may be
Packit 709fb3
   evaluated MANY times!!
Packit 709fb3
Packit 709fb3
   These macros operate a stack of objects.  Each object starts life
Packit 709fb3
   small, and may grow to maturity.  (Consider building a word syllable
Packit 709fb3
   by syllable.)  An object can move while it is growing.  Once it has
Packit 709fb3
   been "finished" it never changes address again.  So the "top of the
Packit 709fb3
   stack" is typically an immature growing object, while the rest of the
Packit 709fb3
   stack is of mature, fixed size and fixed address objects.
Packit 709fb3
Packit 709fb3
   These routines grab large chunks of memory, using a function you
Packit 709fb3
   supply, called 'obstack_chunk_alloc'.  On occasion, they free chunks,
Packit 709fb3
   by calling 'obstack_chunk_free'.  You must define them and declare
Packit 709fb3
   them before using any obstack macros.
Packit 709fb3
Packit 709fb3
   Each independent stack is represented by a 'struct obstack'.
Packit 709fb3
   Each of the obstack macros expects a pointer to such a structure
Packit 709fb3
   as the first argument.
Packit 709fb3
Packit 709fb3
   One motivation for this package is the problem of growing char strings
Packit 709fb3
   in symbol tables.  Unless you are "fascist pig with a read-only mind"
Packit 709fb3
   --Gosper's immortal quote from HAKMEM item 154, out of context--you
Packit 709fb3
   would not like to put any arbitrary upper limit on the length of your
Packit 709fb3
   symbols.
Packit 709fb3
Packit 709fb3
   In practice this often means you will build many short symbols and a
Packit 709fb3
   few long symbols.  At the time you are reading a symbol you don't know
Packit 709fb3
   how long it is.  One traditional method is to read a symbol into a
Packit 709fb3
   buffer, realloc()ating the buffer every time you try to read a symbol
Packit 709fb3
   that is longer than the buffer.  This is beaut, but you still will
Packit 709fb3
   want to copy the symbol from the buffer to a more permanent
Packit 709fb3
   symbol-table entry say about half the time.
Packit 709fb3
Packit 709fb3
   With obstacks, you can work differently.  Use one obstack for all symbol
Packit 709fb3
   names.  As you read a symbol, grow the name in the obstack gradually.
Packit 709fb3
   When the name is complete, finalize it.  Then, if the symbol exists already,
Packit 709fb3
   free the newly read name.
Packit 709fb3
Packit 709fb3
   The way we do this is to take a large chunk, allocating memory from
Packit 709fb3
   low addresses.  When you want to build a symbol in the chunk you just
Packit 709fb3
   add chars above the current "high water mark" in the chunk.  When you
Packit 709fb3
   have finished adding chars, because you got to the end of the symbol,
Packit 709fb3
   you know how long the chars are, and you can create a new object.
Packit 709fb3
   Mostly the chars will not burst over the highest address of the chunk,
Packit 709fb3
   because you would typically expect a chunk to be (say) 100 times as
Packit 709fb3
   long as an average object.
Packit 709fb3
Packit 709fb3
   In case that isn't clear, when we have enough chars to make up
Packit 709fb3
   the object, THEY ARE ALREADY CONTIGUOUS IN THE CHUNK (guaranteed)
Packit 709fb3
   so we just point to it where it lies.  No moving of chars is
Packit 709fb3
   needed and this is the second win: potentially long strings need
Packit 709fb3
   never be explicitly shuffled. Once an object is formed, it does not
Packit 709fb3
   change its address during its lifetime.
Packit 709fb3
Packit 709fb3
   When the chars burst over a chunk boundary, we allocate a larger
Packit 709fb3
   chunk, and then copy the partly formed object from the end of the old
Packit 709fb3
   chunk to the beginning of the new larger chunk.  We then carry on
Packit 709fb3
   accreting characters to the end of the object as we normally would.
Packit 709fb3
Packit 709fb3
   A special macro is provided to add a single char at a time to a
Packit 709fb3
   growing object.  This allows the use of register variables, which
Packit 709fb3
   break the ordinary 'growth' macro.
Packit 709fb3
Packit 709fb3
   Summary:
Packit 709fb3
        We allocate large chunks.
Packit 709fb3
        We carve out one object at a time from the current chunk.
Packit 709fb3
        Once carved, an object never moves.
Packit 709fb3
        We are free to append data of any size to the currently
Packit 709fb3
          growing object.
Packit 709fb3
        Exactly one object is growing in an obstack at any one time.
Packit 709fb3
        You can run one obstack per control block.
Packit 709fb3
        You may have as many control blocks as you dare.
Packit 709fb3
        Because of the way we do it, you can "unwind" an obstack
Packit 709fb3
          back to a previous state. (You may remove objects much
Packit 709fb3
          as you would with a stack.)
Packit 709fb3
 */
Packit 709fb3
Packit 709fb3
Packit 709fb3
/* Don't do the contents of this file more than once.  */
Packit 709fb3
Packit 709fb3
#ifndef _OBSTACK_H
Packit 709fb3
#define _OBSTACK_H 1
Packit 709fb3
Packit 709fb3
#ifndef _OBSTACK_INTERFACE_VERSION
Packit 709fb3
# define _OBSTACK_INTERFACE_VERSION 2
Packit 709fb3
#endif
Packit 709fb3
Packit 709fb3
#include <stddef.h>             /* For size_t and ptrdiff_t.  */
Packit 709fb3
#include <string.h>             /* For __GNU_LIBRARY__, and memcpy.  */
Packit 709fb3
Packit 709fb3
#if __STDC_VERSION__ < 199901L
Packit 709fb3
# define __FLEXIBLE_ARRAY_MEMBER 1
Packit 709fb3
#else
Packit 709fb3
# define __FLEXIBLE_ARRAY_MEMBER
Packit 709fb3
#endif
Packit 709fb3
Packit 709fb3
#if _OBSTACK_INTERFACE_VERSION == 1
Packit 709fb3
/* For binary compatibility with obstack version 1, which used "int"
Packit 709fb3
   and "long" for these two types.  */
Packit 709fb3
# define _OBSTACK_SIZE_T unsigned int
Packit 709fb3
# define _CHUNK_SIZE_T unsigned long
Packit 709fb3
# define _OBSTACK_CAST(type, expr) ((type) (expr))
Packit 709fb3
#else
Packit 709fb3
/* Version 2 with sane types, especially for 64-bit hosts.  */
Packit 709fb3
# define _OBSTACK_SIZE_T size_t
Packit 709fb3
# define _CHUNK_SIZE_T size_t
Packit 709fb3
# define _OBSTACK_CAST(type, expr) (expr)
Packit 709fb3
#endif
Packit 709fb3
Packit 709fb3
/* If B is the base of an object addressed by P, return the result of
Packit 709fb3
   aligning P to the next multiple of A + 1.  B and P must be of type
Packit 709fb3
   char *.  A + 1 must be a power of 2.  */
Packit 709fb3
Packit 709fb3
#define __BPTR_ALIGN(B, P, A) ((B) + (((P) - (B) + (A)) & ~(A)))
Packit 709fb3
Packit 709fb3
/* Similar to __BPTR_ALIGN (B, P, A), except optimize the common case
Packit 709fb3
   where pointers can be converted to integers, aligned as integers,
Packit 709fb3
   and converted back again.  If ptrdiff_t is narrower than a
Packit 709fb3
   pointer (e.g., the AS/400), play it safe and compute the alignment
Packit 709fb3
   relative to B.  Otherwise, use the faster strategy of computing the
Packit 709fb3
   alignment relative to 0.  */
Packit 709fb3
Packit 709fb3
#define __PTR_ALIGN(B, P, A)						      \
Packit 709fb3
  __BPTR_ALIGN (sizeof (ptrdiff_t) < sizeof (void *) ? (B) : (char *) 0,      \
Packit 709fb3
                P, A)
Packit 709fb3
Packit 709fb3
#ifndef __attribute_pure__
Packit 709fb3
# define __attribute_pure__ _GL_ATTRIBUTE_PURE
Packit 709fb3
#endif
Packit 709fb3
Packit 709fb3
/* Not the same as _Noreturn, since it also works with function pointers.  */
Packit 709fb3
#ifndef __attribute_noreturn__
Packit 709fb3
# if 2 < __GNUC__ + (8 <= __GNUC_MINOR__) || 0x5110 <= __SUNPRO_C
Packit 709fb3
#  define __attribute_noreturn__ __attribute__ ((__noreturn__))
Packit 709fb3
# else
Packit 709fb3
#  define __attribute_noreturn__
Packit 709fb3
# endif
Packit 709fb3
#endif
Packit 709fb3
Packit 709fb3
#ifdef __cplusplus
Packit 709fb3
extern "C" {
Packit 709fb3
#endif
Packit 709fb3
Packit 709fb3
struct _obstack_chunk           /* Lives at front of each chunk. */
Packit 709fb3
{
Packit 709fb3
  char *limit;                  /* 1 past end of this chunk */
Packit 709fb3
  struct _obstack_chunk *prev;  /* address of prior chunk or NULL */
Packit 709fb3
  char contents[__FLEXIBLE_ARRAY_MEMBER]; /* objects begin here */
Packit 709fb3
};
Packit 709fb3
Packit 709fb3
struct obstack          /* control current object in current chunk */
Packit 709fb3
{
Packit 709fb3
  _CHUNK_SIZE_T chunk_size;     /* preferred size to allocate chunks in */
Packit 709fb3
  struct _obstack_chunk *chunk; /* address of current struct obstack_chunk */
Packit 709fb3
  char *object_base;            /* address of object we are building */
Packit 709fb3
  char *next_free;              /* where to add next char to current object */
Packit 709fb3
  char *chunk_limit;            /* address of char after current chunk */
Packit 709fb3
  union
Packit 709fb3
  {
Packit 709fb3
    _OBSTACK_SIZE_T i;
Packit 709fb3
    void *p;
Packit 709fb3
  } temp;                       /* Temporary for some macros.  */
Packit 709fb3
  _OBSTACK_SIZE_T alignment_mask;  /* Mask of alignment for each object. */
Packit 709fb3
Packit 709fb3
  /* These prototypes vary based on 'use_extra_arg'.  */
Packit 709fb3
  union
Packit 709fb3
  {
Packit 709fb3
    void *(*plain) (size_t);
Packit 709fb3
    void *(*extra) (void *, size_t);
Packit 709fb3
  } chunkfun;
Packit 709fb3
  union
Packit 709fb3
  {
Packit 709fb3
    void (*plain) (void *);
Packit 709fb3
    void (*extra) (void *, void *);
Packit 709fb3
  } freefun;
Packit 709fb3
Packit 709fb3
  void *extra_arg;              /* first arg for chunk alloc/dealloc funcs */
Packit 709fb3
  unsigned use_extra_arg : 1;     /* chunk alloc/dealloc funcs take extra arg */
Packit 709fb3
  unsigned maybe_empty_object : 1; /* There is a possibility that the current
Packit 709fb3
                                      chunk contains a zero-length object.  This
Packit 709fb3
                                      prevents freeing the chunk if we allocate
Packit 709fb3
                                      a bigger chunk to replace it. */
Packit 709fb3
  unsigned alloc_failed : 1;      /* No longer used, as we now call the failed
Packit 709fb3
                                     handler on error, but retained for binary
Packit 709fb3
                                     compatibility.  */
Packit 709fb3
};
Packit 709fb3
Packit 709fb3
/* Declare the external functions we use; they are in obstack.c.  */
Packit 709fb3
Packit 709fb3
extern void _obstack_newchunk (struct obstack *, _OBSTACK_SIZE_T);
Packit 709fb3
extern void _obstack_free (struct obstack *, void *);
Packit 709fb3
extern int _obstack_begin (struct obstack *,
Packit 709fb3
                           _OBSTACK_SIZE_T, _OBSTACK_SIZE_T,
Packit 709fb3
                           void *(*) (size_t), void (*) (void *));
Packit 709fb3
extern int _obstack_begin_1 (struct obstack *,
Packit 709fb3
                             _OBSTACK_SIZE_T, _OBSTACK_SIZE_T,
Packit 709fb3
                             void *(*) (void *, size_t),
Packit 709fb3
                             void (*) (void *, void *), void *);
Packit 709fb3
extern _OBSTACK_SIZE_T _obstack_memory_used (struct obstack *)
Packit 709fb3
  __attribute_pure__;
Packit 709fb3
Packit 709fb3
Packit 709fb3
/* Error handler called when 'obstack_chunk_alloc' failed to allocate
Packit 709fb3
   more memory.  This can be set to a user defined function which
Packit 709fb3
   should either abort gracefully or use longjump - but shouldn't
Packit 709fb3
   return.  The default action is to print a message and abort.  */
Packit 709fb3
extern __attribute_noreturn__ void (*obstack_alloc_failed_handler) (void);
Packit 709fb3
Packit 709fb3
/* Exit value used when 'print_and_abort' is used.  */
Packit 709fb3
extern int obstack_exit_failure;
Packit 709fb3
Packit 709fb3
/* Pointer to beginning of object being allocated or to be allocated next.
Packit 709fb3
   Note that this might not be the final address of the object
Packit 709fb3
   because a new chunk might be needed to hold the final size.  */
Packit 709fb3
Packit 709fb3
#define obstack_base(h) ((void *) (h)->object_base)
Packit 709fb3
Packit 709fb3
/* Size for allocating ordinary chunks.  */
Packit 709fb3
Packit 709fb3
#define obstack_chunk_size(h) ((h)->chunk_size)
Packit 709fb3
Packit 709fb3
/* Pointer to next byte not yet allocated in current chunk.  */
Packit 709fb3
Packit 709fb3
#define obstack_next_free(h) ((void *) (h)->next_free)
Packit 709fb3
Packit 709fb3
/* Mask specifying low bits that should be clear in address of an object.  */
Packit 709fb3
Packit 709fb3
#define obstack_alignment_mask(h) ((h)->alignment_mask)
Packit 709fb3
Packit 709fb3
/* To prevent prototype warnings provide complete argument list.  */
Packit 709fb3
#define obstack_init(h)							      \
Packit 709fb3
  _obstack_begin ((h), 0, 0,						      \
Packit 709fb3
                  _OBSTACK_CAST (void *(*) (size_t), obstack_chunk_alloc),    \
Packit 709fb3
                  _OBSTACK_CAST (void (*) (void *), obstack_chunk_free))
Packit 709fb3
Packit 709fb3
#define obstack_begin(h, size)						      \
Packit 709fb3
  _obstack_begin ((h), (size), 0,					      \
Packit 709fb3
                  _OBSTACK_CAST (void *(*) (size_t), obstack_chunk_alloc), \
Packit 709fb3
                  _OBSTACK_CAST (void (*) (void *), obstack_chunk_free))
Packit 709fb3
Packit 709fb3
#define obstack_specify_allocation(h, size, alignment, chunkfun, freefun)     \
Packit 709fb3
  _obstack_begin ((h), (size), (alignment),				      \
Packit 709fb3
                  _OBSTACK_CAST (void *(*) (size_t), chunkfun),		      \
Packit 709fb3
                  _OBSTACK_CAST (void (*) (void *), freefun))
Packit 709fb3
Packit 709fb3
#define obstack_specify_allocation_with_arg(h, size, alignment, chunkfun, freefun, arg) \
Packit 709fb3
  _obstack_begin_1 ((h), (size), (alignment),				      \
Packit 709fb3
                    _OBSTACK_CAST (void *(*) (void *, size_t), chunkfun),     \
Packit 709fb3
                    _OBSTACK_CAST (void (*) (void *, void *), freefun), arg)
Packit 709fb3
Packit 709fb3
#define obstack_chunkfun(h, newchunkfun)				      \
Packit 709fb3
  ((void) ((h)->chunkfun.extra = (void *(*) (void *, size_t)) (newchunkfun)))
Packit 709fb3
Packit 709fb3
#define obstack_freefun(h, newfreefun)					      \
Packit 709fb3
  ((void) ((h)->freefun.extra = (void *(*) (void *, void *)) (newfreefun)))
Packit 709fb3
Packit 709fb3
#define obstack_1grow_fast(h, achar) ((void) (*((h)->next_free)++ = (achar)))
Packit 709fb3
Packit 709fb3
#define obstack_blank_fast(h, n) ((void) ((h)->next_free += (n)))
Packit 709fb3
Packit 709fb3
#define obstack_memory_used(h) _obstack_memory_used (h)
Packit 709fb3
Packit 709fb3
#if defined __GNUC__
Packit 709fb3
# if !defined __GNUC_MINOR__ || __GNUC__ * 1000 + __GNUC_MINOR__ < 2008
Packit 709fb3
#  define __extension__
Packit 709fb3
# endif
Packit 709fb3
Packit 709fb3
/* For GNU C, if not -traditional,
Packit 709fb3
   we can define these macros to compute all args only once
Packit 709fb3
   without using a global variable.
Packit 709fb3
   Also, we can avoid using the 'temp' slot, to make faster code.  */
Packit 709fb3
Packit 709fb3
# define obstack_object_size(OBSTACK)					      \
Packit 709fb3
  __extension__								      \
Packit 709fb3
    ({ struct obstack const *__o = (OBSTACK);				      \
Packit 709fb3
       (_OBSTACK_SIZE_T) (__o->next_free - __o->object_base); })
Packit 709fb3
Packit 709fb3
/* The local variable is named __o1 to avoid a shadowed variable
Packit 709fb3
   warning when invoked from other obstack macros.  */
Packit 709fb3
# define obstack_room(OBSTACK)						      \
Packit 709fb3
  __extension__								      \
Packit 709fb3
    ({ struct obstack const *__o1 = (OBSTACK);				      \
Packit 709fb3
       (_OBSTACK_SIZE_T) (__o1->chunk_limit - __o1->next_free); })
Packit 709fb3
Packit 709fb3
# define obstack_make_room(OBSTACK, length)				      \
Packit 709fb3
  __extension__								      \
Packit 709fb3
    ({ struct obstack *__o = (OBSTACK);					      \
Packit 709fb3
       _OBSTACK_SIZE_T __len = (length);				      \
Packit 709fb3
       if (obstack_room (__o) < __len)					      \
Packit 709fb3
         _obstack_newchunk (__o, __len);				      \
Packit 709fb3
       (void) 0; })
Packit 709fb3
Packit 709fb3
# define obstack_empty_p(OBSTACK)					      \
Packit 709fb3
  __extension__								      \
Packit 709fb3
    ({ struct obstack const *__o = (OBSTACK);				      \
Packit 709fb3
       (__o->chunk->prev == 0						      \
Packit 709fb3
        && __o->next_free == __PTR_ALIGN ((char *) __o->chunk,		      \
Packit 709fb3
                                          __o->chunk->contents,		      \
Packit 709fb3
                                          __o->alignment_mask)); })
Packit 709fb3
Packit 709fb3
# define obstack_grow(OBSTACK, where, length)				      \
Packit 709fb3
  __extension__								      \
Packit 709fb3
    ({ struct obstack *__o = (OBSTACK);					      \
Packit 709fb3
       _OBSTACK_SIZE_T __len = (length);				      \
Packit 709fb3
       if (obstack_room (__o) < __len)					      \
Packit 709fb3
         _obstack_newchunk (__o, __len);				      \
Packit 709fb3
       memcpy (__o->next_free, where, __len);				      \
Packit 709fb3
       __o->next_free += __len;						      \
Packit 709fb3
       (void) 0; })
Packit 709fb3
Packit 709fb3
# define obstack_grow0(OBSTACK, where, length)				      \
Packit 709fb3
  __extension__								      \
Packit 709fb3
    ({ struct obstack *__o = (OBSTACK);					      \
Packit 709fb3
       _OBSTACK_SIZE_T __len = (length);				      \
Packit 709fb3
       if (obstack_room (__o) < __len + 1)				      \
Packit 709fb3
         _obstack_newchunk (__o, __len + 1);				      \
Packit 709fb3
       memcpy (__o->next_free, where, __len);				      \
Packit 709fb3
       __o->next_free += __len;						      \
Packit 709fb3
       *(__o->next_free)++ = 0;						      \
Packit 709fb3
       (void) 0; })
Packit 709fb3
Packit 709fb3
# define obstack_1grow(OBSTACK, datum)					      \
Packit 709fb3
  __extension__								      \
Packit 709fb3
    ({ struct obstack *__o = (OBSTACK);					      \
Packit 709fb3
       if (obstack_room (__o) < 1)					      \
Packit 709fb3
         _obstack_newchunk (__o, 1);					      \
Packit 709fb3
       obstack_1grow_fast (__o, datum); })
Packit 709fb3
Packit 709fb3
/* These assume that the obstack alignment is good enough for pointers
Packit 709fb3
   or ints, and that the data added so far to the current object
Packit 709fb3
   shares that much alignment.  */
Packit 709fb3
Packit 709fb3
# define obstack_ptr_grow(OBSTACK, datum)				      \
Packit 709fb3
  __extension__								      \
Packit 709fb3
    ({ struct obstack *__o = (OBSTACK);					      \
Packit 709fb3
       if (obstack_room (__o) < sizeof (void *))			      \
Packit 709fb3
         _obstack_newchunk (__o, sizeof (void *));			      \
Packit 709fb3
       obstack_ptr_grow_fast (__o, datum); })
Packit 709fb3
Packit 709fb3
# define obstack_int_grow(OBSTACK, datum)				      \
Packit 709fb3
  __extension__								      \
Packit 709fb3
    ({ struct obstack *__o = (OBSTACK);					      \
Packit 709fb3
       if (obstack_room (__o) < sizeof (int))				      \
Packit 709fb3
         _obstack_newchunk (__o, sizeof (int));				      \
Packit 709fb3
       obstack_int_grow_fast (__o, datum); })
Packit 709fb3
Packit 709fb3
# define obstack_ptr_grow_fast(OBSTACK, aptr)				      \
Packit 709fb3
  __extension__								      \
Packit 709fb3
    ({ struct obstack *__o1 = (OBSTACK);				      \
Packit 709fb3
       void *__p1 = __o1->next_free;					      \
Packit 709fb3
       *(const void **) __p1 = (aptr);					      \
Packit 709fb3
       __o1->next_free += sizeof (const void *);			      \
Packit 709fb3
       (void) 0; })
Packit 709fb3
Packit 709fb3
# define obstack_int_grow_fast(OBSTACK, aint)				      \
Packit 709fb3
  __extension__								      \
Packit 709fb3
    ({ struct obstack *__o1 = (OBSTACK);				      \
Packit 709fb3
       void *__p1 = __o1->next_free;					      \
Packit 709fb3
       *(int *) __p1 = (aint);						      \
Packit 709fb3
       __o1->next_free += sizeof (int);					      \
Packit 709fb3
       (void) 0; })
Packit 709fb3
Packit 709fb3
# define obstack_blank(OBSTACK, length)					      \
Packit 709fb3
  __extension__								      \
Packit 709fb3
    ({ struct obstack *__o = (OBSTACK);					      \
Packit 709fb3
       _OBSTACK_SIZE_T __len = (length);				      \
Packit 709fb3
       if (obstack_room (__o) < __len)					      \
Packit 709fb3
         _obstack_newchunk (__o, __len);				      \
Packit 709fb3
       obstack_blank_fast (__o, __len); })
Packit 709fb3
Packit 709fb3
# define obstack_alloc(OBSTACK, length)					      \
Packit 709fb3
  __extension__								      \
Packit 709fb3
    ({ struct obstack *__h = (OBSTACK);					      \
Packit 709fb3
       obstack_blank (__h, (length));					      \
Packit 709fb3
       obstack_finish (__h); })
Packit 709fb3
Packit 709fb3
# define obstack_copy(OBSTACK, where, length)				      \
Packit 709fb3
  __extension__								      \
Packit 709fb3
    ({ struct obstack *__h = (OBSTACK);					      \
Packit 709fb3
       obstack_grow (__h, (where), (length));				      \
Packit 709fb3
       obstack_finish (__h); })
Packit 709fb3
Packit 709fb3
# define obstack_copy0(OBSTACK, where, length)				      \
Packit 709fb3
  __extension__								      \
Packit 709fb3
    ({ struct obstack *__h = (OBSTACK);					      \
Packit 709fb3
       obstack_grow0 (__h, (where), (length));				      \
Packit 709fb3
       obstack_finish (__h); })
Packit 709fb3
Packit 709fb3
/* The local variable is named __o1 to avoid a shadowed variable
Packit 709fb3
   warning when invoked from other obstack macros, typically obstack_free.  */
Packit 709fb3
# define obstack_finish(OBSTACK)					      \
Packit 709fb3
  __extension__								      \
Packit 709fb3
    ({ struct obstack *__o1 = (OBSTACK);				      \
Packit 709fb3
       void *__value = (void *) __o1->object_base;			      \
Packit 709fb3
       if (__o1->next_free == __value)					      \
Packit 709fb3
         __o1->maybe_empty_object = 1;					      \
Packit 709fb3
       __o1->next_free							      \
Packit 709fb3
         = __PTR_ALIGN (__o1->object_base, __o1->next_free,		      \
Packit 709fb3
                        __o1->alignment_mask);				      \
Packit 709fb3
       if ((size_t) (__o1->next_free - (char *) __o1->chunk)		      \
Packit 709fb3
           > (size_t) (__o1->chunk_limit - (char *) __o1->chunk))	      \
Packit 709fb3
         __o1->next_free = __o1->chunk_limit;				      \
Packit 709fb3
       __o1->object_base = __o1->next_free;				      \
Packit 709fb3
       __value; })
Packit 709fb3
Packit 709fb3
# define obstack_free(OBSTACK, OBJ)					      \
Packit 709fb3
  __extension__								      \
Packit 709fb3
    ({ struct obstack *__o = (OBSTACK);					      \
Packit 709fb3
       void *__obj = (void *) (OBJ);					      \
Packit 709fb3
       if (__obj > (void *) __o->chunk && __obj < (void *) __o->chunk_limit)  \
Packit 709fb3
         __o->next_free = __o->object_base = (char *) __obj;		      \
Packit 709fb3
       else								      \
Packit 709fb3
         _obstack_free (__o, __obj); })
Packit 709fb3
Packit 709fb3
#else /* not __GNUC__ */
Packit 709fb3
Packit 709fb3
# define obstack_object_size(h)						      \
Packit 709fb3
  ((_OBSTACK_SIZE_T) ((h)->next_free - (h)->object_base))
Packit 709fb3
Packit 709fb3
# define obstack_room(h)						      \
Packit 709fb3
  ((_OBSTACK_SIZE_T) ((h)->chunk_limit - (h)->next_free))
Packit 709fb3
Packit 709fb3
# define obstack_empty_p(h)						      \
Packit 709fb3
  ((h)->chunk->prev == 0						      \
Packit 709fb3
   && (h)->next_free == __PTR_ALIGN ((char *) (h)->chunk,		      \
Packit 709fb3
                                     (h)->chunk->contents,		      \
Packit 709fb3
                                     (h)->alignment_mask))
Packit 709fb3
Packit 709fb3
/* Note that the call to _obstack_newchunk is enclosed in (..., 0)
Packit 709fb3
   so that we can avoid having void expressions
Packit 709fb3
   in the arms of the conditional expression.
Packit 709fb3
   Casting the third operand to void was tried before,
Packit 709fb3
   but some compilers won't accept it.  */
Packit 709fb3
Packit 709fb3
# define obstack_make_room(h, length)					      \
Packit 709fb3
  ((h)->temp.i = (length),						      \
Packit 709fb3
   ((obstack_room (h) < (h)->temp.i)					      \
Packit 709fb3
    ? (_obstack_newchunk (h, (h)->temp.i), 0) : 0),			      \
Packit 709fb3
   (void) 0)
Packit 709fb3
Packit 709fb3
# define obstack_grow(h, where, length)					      \
Packit 709fb3
  ((h)->temp.i = (length),						      \
Packit 709fb3
   ((obstack_room (h) < (h)->temp.i)					      \
Packit 709fb3
   ? (_obstack_newchunk ((h), (h)->temp.i), 0) : 0),			      \
Packit 709fb3
   memcpy ((h)->next_free, where, (h)->temp.i),				      \
Packit 709fb3
   (h)->next_free += (h)->temp.i,					      \
Packit 709fb3
   (void) 0)
Packit 709fb3
Packit 709fb3
# define obstack_grow0(h, where, length)				      \
Packit 709fb3
  ((h)->temp.i = (length),						      \
Packit 709fb3
   ((obstack_room (h) < (h)->temp.i + 1)				      \
Packit 709fb3
   ? (_obstack_newchunk ((h), (h)->temp.i + 1), 0) : 0),		      \
Packit 709fb3
   memcpy ((h)->next_free, where, (h)->temp.i),				      \
Packit 709fb3
   (h)->next_free += (h)->temp.i,					      \
Packit 709fb3
   *((h)->next_free)++ = 0,						      \
Packit 709fb3
   (void) 0)
Packit 709fb3
Packit 709fb3
# define obstack_1grow(h, datum)					      \
Packit 709fb3
  (((obstack_room (h) < 1)						      \
Packit 709fb3
    ? (_obstack_newchunk ((h), 1), 0) : 0),				      \
Packit 709fb3
   obstack_1grow_fast (h, datum))
Packit 709fb3
Packit 709fb3
# define obstack_ptr_grow(h, datum)					      \
Packit 709fb3
  (((obstack_room (h) < sizeof (char *))				      \
Packit 709fb3
    ? (_obstack_newchunk ((h), sizeof (char *)), 0) : 0),		      \
Packit 709fb3
   obstack_ptr_grow_fast (h, datum))
Packit 709fb3
Packit 709fb3
# define obstack_int_grow(h, datum)					      \
Packit 709fb3
  (((obstack_room (h) < sizeof (int))					      \
Packit 709fb3
    ? (_obstack_newchunk ((h), sizeof (int)), 0) : 0),			      \
Packit 709fb3
   obstack_int_grow_fast (h, datum))
Packit 709fb3
Packit 709fb3
# define obstack_ptr_grow_fast(h, aptr)					      \
Packit 709fb3
  (((const void **) ((h)->next_free += sizeof (void *)))[-1] = (aptr),	      \
Packit 709fb3
   (void) 0)
Packit 709fb3
Packit 709fb3
# define obstack_int_grow_fast(h, aint)					      \
Packit 709fb3
  (((int *) ((h)->next_free += sizeof (int)))[-1] = (aint),		      \
Packit 709fb3
   (void) 0)
Packit 709fb3
Packit 709fb3
# define obstack_blank(h, length)					      \
Packit 709fb3
  ((h)->temp.i = (length),						      \
Packit 709fb3
   ((obstack_room (h) < (h)->temp.i)					      \
Packit 709fb3
   ? (_obstack_newchunk ((h), (h)->temp.i), 0) : 0),			      \
Packit 709fb3
   obstack_blank_fast (h, (h)->temp.i))
Packit 709fb3
Packit 709fb3
# define obstack_alloc(h, length)					      \
Packit 709fb3
  (obstack_blank ((h), (length)), obstack_finish ((h)))
Packit 709fb3
Packit 709fb3
# define obstack_copy(h, where, length)					      \
Packit 709fb3
  (obstack_grow ((h), (where), (length)), obstack_finish ((h)))
Packit 709fb3
Packit 709fb3
# define obstack_copy0(h, where, length)				      \
Packit 709fb3
  (obstack_grow0 ((h), (where), (length)), obstack_finish ((h)))
Packit 709fb3
Packit 709fb3
# define obstack_finish(h)						      \
Packit 709fb3
  (((h)->next_free == (h)->object_base					      \
Packit 709fb3
    ? (((h)->maybe_empty_object = 1), 0)				      \
Packit 709fb3
    : 0),								      \
Packit 709fb3
   (h)->temp.p = (h)->object_base,					      \
Packit 709fb3
   (h)->next_free							      \
Packit 709fb3
     = __PTR_ALIGN ((h)->object_base, (h)->next_free,			      \
Packit 709fb3
                    (h)->alignment_mask),				      \
Packit 709fb3
   (((size_t) ((h)->next_free - (char *) (h)->chunk)			      \
Packit 709fb3
     > (size_t) ((h)->chunk_limit - (char *) (h)->chunk))		      \
Packit 709fb3
   ? ((h)->next_free = (h)->chunk_limit) : 0),				      \
Packit 709fb3
   (h)->object_base = (h)->next_free,					      \
Packit 709fb3
   (h)->temp.p)
Packit 709fb3
Packit 709fb3
# define obstack_free(h, obj)						      \
Packit 709fb3
  ((h)->temp.p = (void *) (obj),					      \
Packit 709fb3
   (((h)->temp.p > (void *) (h)->chunk					      \
Packit 709fb3
     && (h)->temp.p < (void *) (h)->chunk_limit)			      \
Packit 709fb3
    ? (void) ((h)->next_free = (h)->object_base = (char *) (h)->temp.p)       \
Packit 709fb3
    : _obstack_free ((h), (h)->temp.p)))
Packit 709fb3
Packit 709fb3
#endif /* not __GNUC__ */
Packit 709fb3
Packit 709fb3
#ifdef __cplusplus
Packit 709fb3
}       /* C++ */
Packit 709fb3
#endif
Packit 709fb3
Packit 709fb3
#endif /* _OBSTACK_H */