Blame include/obstack.h

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