Blame malloc/obstack.h

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