xref: /netbsd-src/external/gpl3/gdb/dist/include/obstack.h (revision e663ba6e3a60083e70de702e9d54bf486a57b6a7)
198b9484cSchristos /* obstack.h - object stack macros
2*e663ba6eSchristos    Copyright (C) 1988-2024 Free Software Foundation, Inc.
3ba340e45Schristos    This file is part of the GNU C Library.
498b9484cSchristos 
5ba340e45Schristos    The GNU C Library is free software; you can redistribute it and/or
6ba340e45Schristos    modify it under the terms of the GNU Lesser General Public
7ba340e45Schristos    License as published by the Free Software Foundation; either
8ba340e45Schristos    version 2.1 of the License, or (at your option) any later version.
998b9484cSchristos 
10ba340e45Schristos    The GNU C Library is distributed in the hope that it will be useful,
1198b9484cSchristos    but WITHOUT ANY WARRANTY; without even the implied warranty of
12ba340e45Schristos    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13ba340e45Schristos    Lesser General Public License for more details.
1498b9484cSchristos 
15ba340e45Schristos    You should have received a copy of the GNU Lesser General Public
16ba340e45Schristos    License along with the GNU C Library; if not, see
17ba340e45Schristos    <http://www.gnu.org/licenses/>.  */
1898b9484cSchristos 
1998b9484cSchristos /* Summary:
2098b9484cSchristos 
2198b9484cSchristos    All the apparent functions defined here are macros. The idea
2298b9484cSchristos    is that you would use these pre-tested macros to solve a
2398b9484cSchristos    very specific set of problems, and they would run fast.
2498b9484cSchristos    Caution: no side-effects in arguments please!! They may be
2598b9484cSchristos    evaluated MANY times!!
2698b9484cSchristos 
2798b9484cSchristos    These macros operate a stack of objects.  Each object starts life
2898b9484cSchristos    small, and may grow to maturity.  (Consider building a word syllable
2998b9484cSchristos    by syllable.)  An object can move while it is growing.  Once it has
3098b9484cSchristos    been "finished" it never changes address again.  So the "top of the
3198b9484cSchristos    stack" is typically an immature growing object, while the rest of the
3298b9484cSchristos    stack is of mature, fixed size and fixed address objects.
3398b9484cSchristos 
3498b9484cSchristos    These routines grab large chunks of memory, using a function you
35ba340e45Schristos    supply, called 'obstack_chunk_alloc'.  On occasion, they free chunks,
36ba340e45Schristos    by calling 'obstack_chunk_free'.  You must define them and declare
3798b9484cSchristos    them before using any obstack macros.
3898b9484cSchristos 
39ba340e45Schristos    Each independent stack is represented by a 'struct obstack'.
4098b9484cSchristos    Each of the obstack macros expects a pointer to such a structure
4198b9484cSchristos    as the first argument.
4298b9484cSchristos 
4398b9484cSchristos    One motivation for this package is the problem of growing char strings
4498b9484cSchristos    in symbol tables.  Unless you are "fascist pig with a read-only mind"
4598b9484cSchristos    --Gosper's immortal quote from HAKMEM item 154, out of context--you
4698b9484cSchristos    would not like to put any arbitrary upper limit on the length of your
4798b9484cSchristos    symbols.
4898b9484cSchristos 
4998b9484cSchristos    In practice this often means you will build many short symbols and a
5098b9484cSchristos    few long symbols.  At the time you are reading a symbol you don't know
5198b9484cSchristos    how long it is.  One traditional method is to read a symbol into a
5298b9484cSchristos    buffer, realloc()ating the buffer every time you try to read a symbol
5398b9484cSchristos    that is longer than the buffer.  This is beaut, but you still will
5498b9484cSchristos    want to copy the symbol from the buffer to a more permanent
5598b9484cSchristos    symbol-table entry say about half the time.
5698b9484cSchristos 
5798b9484cSchristos    With obstacks, you can work differently.  Use one obstack for all symbol
5898b9484cSchristos    names.  As you read a symbol, grow the name in the obstack gradually.
5998b9484cSchristos    When the name is complete, finalize it.  Then, if the symbol exists already,
6098b9484cSchristos    free the newly read name.
6198b9484cSchristos 
6298b9484cSchristos    The way we do this is to take a large chunk, allocating memory from
6398b9484cSchristos    low addresses.  When you want to build a symbol in the chunk you just
6498b9484cSchristos    add chars above the current "high water mark" in the chunk.  When you
6598b9484cSchristos    have finished adding chars, because you got to the end of the symbol,
6698b9484cSchristos    you know how long the chars are, and you can create a new object.
6798b9484cSchristos    Mostly the chars will not burst over the highest address of the chunk,
6898b9484cSchristos    because you would typically expect a chunk to be (say) 100 times as
6998b9484cSchristos    long as an average object.
7098b9484cSchristos 
7198b9484cSchristos    In case that isn't clear, when we have enough chars to make up
7298b9484cSchristos    the object, THEY ARE ALREADY CONTIGUOUS IN THE CHUNK (guaranteed)
7398b9484cSchristos    so we just point to it where it lies.  No moving of chars is
7498b9484cSchristos    needed and this is the second win: potentially long strings need
7598b9484cSchristos    never be explicitly shuffled. Once an object is formed, it does not
7698b9484cSchristos    change its address during its lifetime.
7798b9484cSchristos 
7898b9484cSchristos    When the chars burst over a chunk boundary, we allocate a larger
7998b9484cSchristos    chunk, and then copy the partly formed object from the end of the old
8098b9484cSchristos    chunk to the beginning of the new larger chunk.  We then carry on
8198b9484cSchristos    accreting characters to the end of the object as we normally would.
8298b9484cSchristos 
8398b9484cSchristos    A special macro is provided to add a single char at a time to a
8498b9484cSchristos    growing object.  This allows the use of register variables, which
8598b9484cSchristos    break the ordinary 'growth' macro.
8698b9484cSchristos 
8798b9484cSchristos    Summary:
8898b9484cSchristos         We allocate large chunks.
8998b9484cSchristos         We carve out one object at a time from the current chunk.
9098b9484cSchristos         Once carved, an object never moves.
9198b9484cSchristos         We are free to append data of any size to the currently
9298b9484cSchristos           growing object.
9398b9484cSchristos         Exactly one object is growing in an obstack at any one time.
9498b9484cSchristos         You can run one obstack per control block.
9598b9484cSchristos         You may have as many control blocks as you dare.
96ba340e45Schristos         Because of the way we do it, you can "unwind" an obstack
9798b9484cSchristos           back to a previous state. (You may remove objects much
9898b9484cSchristos           as you would with a stack.)
9998b9484cSchristos  */
10098b9484cSchristos 
10198b9484cSchristos 
10298b9484cSchristos /* Don't do the contents of this file more than once.  */
10398b9484cSchristos 
10498b9484cSchristos #ifndef _OBSTACK_H
10598b9484cSchristos #define _OBSTACK_H 1
10698b9484cSchristos 
107ba340e45Schristos #ifndef _OBSTACK_INTERFACE_VERSION
108ba340e45Schristos # define _OBSTACK_INTERFACE_VERSION 2
109ba340e45Schristos #endif
110ba340e45Schristos 
111ba340e45Schristos #include <stddef.h>             /* For size_t and ptrdiff_t.  */
112ba340e45Schristos #include <string.h>             /* For __GNU_LIBRARY__, and memcpy.  */
113ba340e45Schristos 
114ba340e45Schristos #if _OBSTACK_INTERFACE_VERSION == 1
115ba340e45Schristos /* For binary compatibility with obstack version 1, which used "int"
116ba340e45Schristos    and "long" for these two types.  */
117ba340e45Schristos # define _OBSTACK_SIZE_T unsigned int
118ba340e45Schristos # define _CHUNK_SIZE_T unsigned long
119ba340e45Schristos # define _OBSTACK_CAST(type, expr) ((type) (expr))
120ba340e45Schristos #else
121ba340e45Schristos /* Version 2 with sane types, especially for 64-bit hosts.  */
122ba340e45Schristos # define _OBSTACK_SIZE_T size_t
123ba340e45Schristos # define _CHUNK_SIZE_T size_t
124ba340e45Schristos # define _OBSTACK_CAST(type, expr) (expr)
125ba340e45Schristos #endif
126ba340e45Schristos 
127ba340e45Schristos /* If B is the base of an object addressed by P, return the result of
128ba340e45Schristos    aligning P to the next multiple of A + 1.  B and P must be of type
129ba340e45Schristos    char *.  A + 1 must be a power of 2.  */
130ba340e45Schristos 
131ba340e45Schristos #define __BPTR_ALIGN(B, P, A) ((B) + (((P) - (B) + (A)) & ~(A)))
132ba340e45Schristos 
133ba340e45Schristos /* Similar to __BPTR_ALIGN (B, P, A), except optimize the common case
134ba340e45Schristos    where pointers can be converted to integers, aligned as integers,
135ba340e45Schristos    and converted back again.  If ptrdiff_t is narrower than a
136ba340e45Schristos    pointer (e.g., the AS/400), play it safe and compute the alignment
137ba340e45Schristos    relative to B.  Otherwise, use the faster strategy of computing the
138ba340e45Schristos    alignment relative to 0.  */
139ba340e45Schristos 
140ba340e45Schristos #define __PTR_ALIGN(B, P, A)						\
1414b169a6bSchristos   (sizeof (ptrdiff_t) < sizeof (void *) ? __BPTR_ALIGN (B, P, A)	\
1424b169a6bSchristos    : (char *) (((ptrdiff_t) (P) + (A)) & ~(A)))
143ba340e45Schristos 
144ba340e45Schristos #ifndef __attribute_pure__
145ba340e45Schristos # if defined __GNUC_MINOR__ && __GNUC__ * 1000 + __GNUC_MINOR__ >= 2096
146ba340e45Schristos #  define __attribute_pure__ __attribute__ ((__pure__))
147ba340e45Schristos # else
148ba340e45Schristos #  define __attribute_pure__
149ba340e45Schristos # endif
150ba340e45Schristos #endif
151ba340e45Schristos 
15298b9484cSchristos #ifdef __cplusplus
15398b9484cSchristos extern "C" {
15498b9484cSchristos #endif
15598b9484cSchristos 
15698b9484cSchristos struct _obstack_chunk           /* Lives at front of each chunk. */
15798b9484cSchristos {
15898b9484cSchristos   char *limit;                  /* 1 past end of this chunk */
15998b9484cSchristos   struct _obstack_chunk *prev;  /* address of prior chunk or NULL */
16098b9484cSchristos   char contents[4];             /* objects begin here */
16198b9484cSchristos };
16298b9484cSchristos 
16398b9484cSchristos struct obstack          /* control current object in current chunk */
16498b9484cSchristos {
165ba340e45Schristos   _CHUNK_SIZE_T chunk_size;     /* preferred size to allocate chunks in */
16698b9484cSchristos   struct _obstack_chunk *chunk; /* address of current struct obstack_chunk */
16798b9484cSchristos   char *object_base;            /* address of object we are building */
16898b9484cSchristos   char *next_free;              /* where to add next char to current object */
16998b9484cSchristos   char *chunk_limit;            /* address of char after current chunk */
170ba340e45Schristos   union
171ba340e45Schristos   {
172ba340e45Schristos     _OBSTACK_SIZE_T i;
173ba340e45Schristos     void *p;
174ba340e45Schristos   } temp;                       /* Temporary for some macros.  */
175ba340e45Schristos   _OBSTACK_SIZE_T alignment_mask;  /* Mask of alignment for each object. */
176ba340e45Schristos 
177ba340e45Schristos   /* These prototypes vary based on 'use_extra_arg'.  */
178ba340e45Schristos   union
179ba340e45Schristos   {
180ba340e45Schristos     void *(*plain) (size_t);
181ba340e45Schristos     void *(*extra) (void *, size_t);
182ba340e45Schristos   } chunkfun;
183ba340e45Schristos   union
184ba340e45Schristos   {
185ba340e45Schristos     void (*plain) (void *);
186ba340e45Schristos     void (*extra) (void *, void *);
187ba340e45Schristos   } freefun;
188ba340e45Schristos 
18998b9484cSchristos   void *extra_arg;              /* first arg for chunk alloc/dealloc funcs */
19098b9484cSchristos   unsigned use_extra_arg : 1;     /* chunk alloc/dealloc funcs take extra arg */
19198b9484cSchristos   unsigned maybe_empty_object : 1; /* There is a possibility that the current
19298b9484cSchristos                                       chunk contains a zero-length object.  This
19398b9484cSchristos                                       prevents freeing the chunk if we allocate
19498b9484cSchristos                                       a bigger chunk to replace it. */
19598b9484cSchristos   unsigned alloc_failed : 1;      /* No longer used, as we now call the failed
19698b9484cSchristos                                      handler on error, but retained for binary
19798b9484cSchristos                                      compatibility.  */
19898b9484cSchristos };
19998b9484cSchristos 
20098b9484cSchristos /* Declare the external functions we use; they are in obstack.c.  */
20198b9484cSchristos 
202ba340e45Schristos extern void _obstack_newchunk (struct obstack *, _OBSTACK_SIZE_T);
20398b9484cSchristos extern void _obstack_free (struct obstack *, void *);
204ba340e45Schristos extern int _obstack_begin (struct obstack *,
205ba340e45Schristos                            _OBSTACK_SIZE_T, _OBSTACK_SIZE_T,
206ba340e45Schristos                            void *(*) (size_t), void (*) (void *));
207ba340e45Schristos extern int _obstack_begin_1 (struct obstack *,
208ba340e45Schristos                              _OBSTACK_SIZE_T, _OBSTACK_SIZE_T,
209ba340e45Schristos                              void *(*) (void *, size_t),
21098b9484cSchristos                              void (*) (void *, void *), void *);
211ba340e45Schristos extern _OBSTACK_SIZE_T _obstack_memory_used (struct obstack *)
212ba340e45Schristos   __attribute_pure__;
21398b9484cSchristos 
21498b9484cSchristos 
215ba340e45Schristos /* Error handler called when 'obstack_chunk_alloc' failed to allocate
216ba340e45Schristos    more memory.  This can be set to a user defined function which
217ba340e45Schristos    should either abort gracefully or use longjump - but shouldn't
218ba340e45Schristos    return.  The default action is to print a message and abort.  */
21998b9484cSchristos extern void (*obstack_alloc_failed_handler) (void);
22098b9484cSchristos 
221ba340e45Schristos /* Exit value used when 'print_and_abort' is used.  */
22298b9484cSchristos extern int obstack_exit_failure;
223ba340e45Schristos 
22498b9484cSchristos /* Pointer to beginning of object being allocated or to be allocated next.
22598b9484cSchristos    Note that this might not be the final address of the object
22698b9484cSchristos    because a new chunk might be needed to hold the final size.  */
22798b9484cSchristos 
228ba340e45Schristos #define obstack_base(h) ((void *) (h)->object_base)
22998b9484cSchristos 
23098b9484cSchristos /* Size for allocating ordinary chunks.  */
23198b9484cSchristos 
23298b9484cSchristos #define obstack_chunk_size(h) ((h)->chunk_size)
23398b9484cSchristos 
23498b9484cSchristos /* Pointer to next byte not yet allocated in current chunk.  */
23598b9484cSchristos 
236ba340e45Schristos #define obstack_next_free(h) ((void *) (h)->next_free)
23798b9484cSchristos 
23898b9484cSchristos /* Mask specifying low bits that should be clear in address of an object.  */
23998b9484cSchristos 
24098b9484cSchristos #define obstack_alignment_mask(h) ((h)->alignment_mask)
24198b9484cSchristos 
242ba340e45Schristos /* To prevent prototype warnings provide complete argument list.  */
24398b9484cSchristos #define obstack_init(h)							      \
24498b9484cSchristos   _obstack_begin ((h), 0, 0,						      \
245ba340e45Schristos                   _OBSTACK_CAST (void *(*) (size_t), obstack_chunk_alloc),    \
246ba340e45Schristos                   _OBSTACK_CAST (void (*) (void *), obstack_chunk_free))
24798b9484cSchristos 
24898b9484cSchristos #define obstack_begin(h, size)						      \
24998b9484cSchristos   _obstack_begin ((h), (size), 0,					      \
250ba340e45Schristos                   _OBSTACK_CAST (void *(*) (size_t), obstack_chunk_alloc), \
251ba340e45Schristos                   _OBSTACK_CAST (void (*) (void *), obstack_chunk_free))
25298b9484cSchristos 
25398b9484cSchristos #define obstack_specify_allocation(h, size, alignment, chunkfun, freefun)     \
25498b9484cSchristos   _obstack_begin ((h), (size), (alignment),				      \
255ba340e45Schristos                   _OBSTACK_CAST (void *(*) (size_t), chunkfun),		      \
256ba340e45Schristos                   _OBSTACK_CAST (void (*) (void *), freefun))
25798b9484cSchristos 
25898b9484cSchristos #define obstack_specify_allocation_with_arg(h, size, alignment, chunkfun, freefun, arg) \
25998b9484cSchristos   _obstack_begin_1 ((h), (size), (alignment),				      \
260ba340e45Schristos                     _OBSTACK_CAST (void *(*) (void *, size_t), chunkfun),     \
261ba340e45Schristos                     _OBSTACK_CAST (void (*) (void *, void *), freefun), arg)
26298b9484cSchristos 
26398b9484cSchristos #define obstack_chunkfun(h, newchunkfun)				      \
264ba340e45Schristos   ((void) ((h)->chunkfun.extra = (void *(*) (void *, size_t)) (newchunkfun)))
26598b9484cSchristos 
26698b9484cSchristos #define obstack_freefun(h, newfreefun)					      \
267ba340e45Schristos   ((void) ((h)->freefun.extra = (void *(*) (void *, void *)) (newfreefun)))
26898b9484cSchristos 
269ba340e45Schristos #define obstack_1grow_fast(h, achar) ((void) (*((h)->next_free)++ = (achar)))
27098b9484cSchristos 
271ba340e45Schristos #define obstack_blank_fast(h, n) ((void) ((h)->next_free += (n)))
27298b9484cSchristos 
27398b9484cSchristos #define obstack_memory_used(h) _obstack_memory_used (h)
274ba340e45Schristos 
275ba340e45Schristos #if defined __GNUC__
276ba340e45Schristos # if !defined __GNUC_MINOR__ || __GNUC__ * 1000 + __GNUC_MINOR__ < 2008
27798b9484cSchristos #  define __extension__
27898b9484cSchristos # endif
27998b9484cSchristos 
28098b9484cSchristos /* For GNU C, if not -traditional,
28198b9484cSchristos    we can define these macros to compute all args only once
28298b9484cSchristos    without using a global variable.
283ba340e45Schristos    Also, we can avoid using the 'temp' slot, to make faster code.  */
28498b9484cSchristos 
28598b9484cSchristos # define obstack_object_size(OBSTACK)					      \
28698b9484cSchristos   __extension__								      \
287ba340e45Schristos     ({ struct obstack const *__o = (OBSTACK);				      \
288ba340e45Schristos        (_OBSTACK_SIZE_T) (__o->next_free - __o->object_base); })
28998b9484cSchristos 
290ba340e45Schristos /* The local variable is named __o1 to avoid a shadowed variable
291ba340e45Schristos    warning when invoked from other obstack macros.  */
29298b9484cSchristos # define obstack_room(OBSTACK)						      \
29398b9484cSchristos   __extension__								      \
294ba340e45Schristos     ({ struct obstack const *__o1 = (OBSTACK);				      \
295ba340e45Schristos        (_OBSTACK_SIZE_T) (__o1->chunk_limit - __o1->next_free); })
29698b9484cSchristos 
29798b9484cSchristos # define obstack_make_room(OBSTACK, length)				      \
29898b9484cSchristos   __extension__								      \
29998b9484cSchristos     ({ struct obstack *__o = (OBSTACK);					      \
300ba340e45Schristos        _OBSTACK_SIZE_T __len = (length);				      \
301ba340e45Schristos        if (obstack_room (__o) < __len)					      \
30298b9484cSchristos          _obstack_newchunk (__o, __len);				      \
30398b9484cSchristos        (void) 0; })
30498b9484cSchristos 
30598b9484cSchristos # define obstack_empty_p(OBSTACK)					      \
30698b9484cSchristos   __extension__								      \
307ba340e45Schristos     ({ struct obstack const *__o = (OBSTACK);				      \
308ba340e45Schristos        (__o->chunk->prev == 0						      \
309ba340e45Schristos         && __o->next_free == __PTR_ALIGN ((char *) __o->chunk,		      \
310ba340e45Schristos                                           __o->chunk->contents,		      \
311ba340e45Schristos                                           __o->alignment_mask)); })
31298b9484cSchristos 
31398b9484cSchristos # define obstack_grow(OBSTACK, where, length)				      \
31498b9484cSchristos   __extension__								      \
31598b9484cSchristos     ({ struct obstack *__o = (OBSTACK);					      \
316ba340e45Schristos        _OBSTACK_SIZE_T __len = (length);				      \
317ba340e45Schristos        if (obstack_room (__o) < __len)					      \
31898b9484cSchristos          _obstack_newchunk (__o, __len);				      \
319ba340e45Schristos        memcpy (__o->next_free, where, __len);				      \
32098b9484cSchristos        __o->next_free += __len;						      \
32198b9484cSchristos        (void) 0; })
32298b9484cSchristos 
32398b9484cSchristos # define obstack_grow0(OBSTACK, where, length)				      \
32498b9484cSchristos   __extension__								      \
32598b9484cSchristos     ({ struct obstack *__o = (OBSTACK);					      \
326ba340e45Schristos        _OBSTACK_SIZE_T __len = (length);				      \
327ba340e45Schristos        if (obstack_room (__o) < __len + 1)				      \
32898b9484cSchristos          _obstack_newchunk (__o, __len + 1);				      \
329ba340e45Schristos        memcpy (__o->next_free, where, __len);				      \
33098b9484cSchristos        __o->next_free += __len;						      \
33198b9484cSchristos        *(__o->next_free)++ = 0;						      \
33298b9484cSchristos        (void) 0; })
33398b9484cSchristos 
33498b9484cSchristos # define obstack_1grow(OBSTACK, datum)					      \
33598b9484cSchristos   __extension__								      \
33698b9484cSchristos     ({ struct obstack *__o = (OBSTACK);					      \
337ba340e45Schristos        if (obstack_room (__o) < 1)					      \
33898b9484cSchristos          _obstack_newchunk (__o, 1);					      \
339ba340e45Schristos        obstack_1grow_fast (__o, datum); })
34098b9484cSchristos 
341ba340e45Schristos /* These assume that the obstack alignment is good enough for pointers
342ba340e45Schristos    or ints, and that the data added so far to the current object
34398b9484cSchristos    shares that much alignment.  */
34498b9484cSchristos 
34598b9484cSchristos # define obstack_ptr_grow(OBSTACK, datum)				      \
34698b9484cSchristos   __extension__								      \
34798b9484cSchristos     ({ struct obstack *__o = (OBSTACK);					      \
348ba340e45Schristos        if (obstack_room (__o) < sizeof (void *))			      \
34998b9484cSchristos          _obstack_newchunk (__o, sizeof (void *));			      \
35098b9484cSchristos        obstack_ptr_grow_fast (__o, datum); })
35198b9484cSchristos 
35298b9484cSchristos # define obstack_int_grow(OBSTACK, datum)				      \
35398b9484cSchristos   __extension__								      \
35498b9484cSchristos     ({ struct obstack *__o = (OBSTACK);					      \
355ba340e45Schristos        if (obstack_room (__o) < sizeof (int))				      \
35698b9484cSchristos          _obstack_newchunk (__o, sizeof (int));				      \
35798b9484cSchristos        obstack_int_grow_fast (__o, datum); })
35898b9484cSchristos 
35998b9484cSchristos # define obstack_ptr_grow_fast(OBSTACK, aptr)				      \
36098b9484cSchristos   __extension__								      \
36198b9484cSchristos     ({ struct obstack *__o1 = (OBSTACK);				      \
362ba340e45Schristos        void *__p1 = __o1->next_free;					      \
363ba340e45Schristos        *(const void **) __p1 = (aptr);					      \
36498b9484cSchristos        __o1->next_free += sizeof (const void *);			      \
36598b9484cSchristos        (void) 0; })
36698b9484cSchristos 
36798b9484cSchristos # define obstack_int_grow_fast(OBSTACK, aint)				      \
36898b9484cSchristos   __extension__								      \
36998b9484cSchristos     ({ struct obstack *__o1 = (OBSTACK);				      \
370ba340e45Schristos        void *__p1 = __o1->next_free;					      \
371ba340e45Schristos        *(int *) __p1 = (aint);						      \
37298b9484cSchristos        __o1->next_free += sizeof (int);					      \
37398b9484cSchristos        (void) 0; })
37498b9484cSchristos 
37598b9484cSchristos # define obstack_blank(OBSTACK, length)					      \
37698b9484cSchristos   __extension__								      \
37798b9484cSchristos     ({ struct obstack *__o = (OBSTACK);					      \
378ba340e45Schristos        _OBSTACK_SIZE_T __len = (length);				      \
379ba340e45Schristos        if (obstack_room (__o) < __len)					      \
38098b9484cSchristos          _obstack_newchunk (__o, __len);				      \
381ba340e45Schristos        obstack_blank_fast (__o, __len); })
38298b9484cSchristos 
38398b9484cSchristos # define obstack_alloc(OBSTACK, length)					      \
38498b9484cSchristos   __extension__								      \
38598b9484cSchristos     ({ struct obstack *__h = (OBSTACK);					      \
38698b9484cSchristos        obstack_blank (__h, (length));					      \
38798b9484cSchristos        obstack_finish (__h); })
38898b9484cSchristos 
38998b9484cSchristos # define obstack_copy(OBSTACK, where, length)				      \
39098b9484cSchristos   __extension__								      \
39198b9484cSchristos     ({ struct obstack *__h = (OBSTACK);					      \
39298b9484cSchristos        obstack_grow (__h, (where), (length));				      \
39398b9484cSchristos        obstack_finish (__h); })
39498b9484cSchristos 
39598b9484cSchristos # define obstack_copy0(OBSTACK, where, length)				      \
39698b9484cSchristos   __extension__								      \
39798b9484cSchristos     ({ struct obstack *__h = (OBSTACK);					      \
39898b9484cSchristos        obstack_grow0 (__h, (where), (length));				      \
39998b9484cSchristos        obstack_finish (__h); })
40098b9484cSchristos 
401ba340e45Schristos /* The local variable is named __o1 to avoid a shadowed variable
402ba340e45Schristos    warning when invoked from other obstack macros, typically obstack_free.  */
40398b9484cSchristos # define obstack_finish(OBSTACK)					      \
40498b9484cSchristos   __extension__								      \
40598b9484cSchristos     ({ struct obstack *__o1 = (OBSTACK);				      \
406ba340e45Schristos        void *__value = (void *) __o1->object_base;			      \
407ba340e45Schristos        if (__o1->next_free == __value)					      \
40898b9484cSchristos          __o1->maybe_empty_object = 1;					      \
40998b9484cSchristos        __o1->next_free							      \
410ba340e45Schristos          = __PTR_ALIGN (__o1->object_base, __o1->next_free,		      \
411ba340e45Schristos                         __o1->alignment_mask);				      \
412ba340e45Schristos        if ((size_t) (__o1->next_free - (char *) __o1->chunk)		      \
413ba340e45Schristos            > (size_t) (__o1->chunk_limit - (char *) __o1->chunk))	      \
41498b9484cSchristos          __o1->next_free = __o1->chunk_limit;				      \
41598b9484cSchristos        __o1->object_base = __o1->next_free;				      \
416ba340e45Schristos        __value; })
41798b9484cSchristos 
41898b9484cSchristos # define obstack_free(OBSTACK, OBJ)					      \
41998b9484cSchristos   __extension__								      \
42098b9484cSchristos     ({ struct obstack *__o = (OBSTACK);					      \
42198b9484cSchristos        void *__obj = (void *) (OBJ);					      \
42298b9484cSchristos        if (__obj > (void *) __o->chunk && __obj < (void *) __o->chunk_limit)  \
42398b9484cSchristos          __o->next_free = __o->object_base = (char *) __obj;		      \
424ba340e45Schristos        else								      \
425ba340e45Schristos          _obstack_free (__o, __obj); })
426ba340e45Schristos 
427ba340e45Schristos #else /* not __GNUC__ */
42898b9484cSchristos 
42998b9484cSchristos # define obstack_object_size(h)						      \
430ba340e45Schristos   ((_OBSTACK_SIZE_T) ((h)->next_free - (h)->object_base))
43198b9484cSchristos 
43298b9484cSchristos # define obstack_room(h)						      \
433ba340e45Schristos   ((_OBSTACK_SIZE_T) ((h)->chunk_limit - (h)->next_free))
43498b9484cSchristos 
43598b9484cSchristos # define obstack_empty_p(h)						      \
436ba340e45Schristos   ((h)->chunk->prev == 0						      \
437ba340e45Schristos    && (h)->next_free == __PTR_ALIGN ((char *) (h)->chunk,		      \
438ba340e45Schristos                                      (h)->chunk->contents,		      \
439ba340e45Schristos                                      (h)->alignment_mask))
44098b9484cSchristos 
44198b9484cSchristos /* Note that the call to _obstack_newchunk is enclosed in (..., 0)
44298b9484cSchristos    so that we can avoid having void expressions
44398b9484cSchristos    in the arms of the conditional expression.
44498b9484cSchristos    Casting the third operand to void was tried before,
44598b9484cSchristos    but some compilers won't accept it.  */
44698b9484cSchristos 
44798b9484cSchristos # define obstack_make_room(h, length)					      \
448ba340e45Schristos   ((h)->temp.i = (length),						      \
449ba340e45Schristos    ((obstack_room (h) < (h)->temp.i)					      \
450ba340e45Schristos     ? (_obstack_newchunk (h, (h)->temp.i), 0) : 0),			      \
451ba340e45Schristos    (void) 0)
45298b9484cSchristos 
45398b9484cSchristos # define obstack_grow(h, where, length)					      \
454ba340e45Schristos   ((h)->temp.i = (length),						      \
455ba340e45Schristos    ((obstack_room (h) < (h)->temp.i)					      \
456ba340e45Schristos    ? (_obstack_newchunk ((h), (h)->temp.i), 0) : 0),			      \
457ba340e45Schristos    memcpy ((h)->next_free, where, (h)->temp.i),				      \
458ba340e45Schristos    (h)->next_free += (h)->temp.i,					      \
459ba340e45Schristos    (void) 0)
46098b9484cSchristos 
46198b9484cSchristos # define obstack_grow0(h, where, length)				      \
462ba340e45Schristos   ((h)->temp.i = (length),						      \
463ba340e45Schristos    ((obstack_room (h) < (h)->temp.i + 1)				      \
464ba340e45Schristos    ? (_obstack_newchunk ((h), (h)->temp.i + 1), 0) : 0),		      \
465ba340e45Schristos    memcpy ((h)->next_free, where, (h)->temp.i),				      \
466ba340e45Schristos    (h)->next_free += (h)->temp.i,					      \
467ba340e45Schristos    *((h)->next_free)++ = 0,						      \
468ba340e45Schristos    (void) 0)
46998b9484cSchristos 
47098b9484cSchristos # define obstack_1grow(h, datum)					      \
471ba340e45Schristos   (((obstack_room (h) < 1)						      \
47298b9484cSchristos     ? (_obstack_newchunk ((h), 1), 0) : 0),				      \
47398b9484cSchristos    obstack_1grow_fast (h, datum))
47498b9484cSchristos 
47598b9484cSchristos # define obstack_ptr_grow(h, datum)					      \
476ba340e45Schristos   (((obstack_room (h) < sizeof (char *))				      \
47798b9484cSchristos     ? (_obstack_newchunk ((h), sizeof (char *)), 0) : 0),		      \
47898b9484cSchristos    obstack_ptr_grow_fast (h, datum))
47998b9484cSchristos 
48098b9484cSchristos # define obstack_int_grow(h, datum)					      \
481ba340e45Schristos   (((obstack_room (h) < sizeof (int))					      \
48298b9484cSchristos     ? (_obstack_newchunk ((h), sizeof (int)), 0) : 0),			      \
48398b9484cSchristos    obstack_int_grow_fast (h, datum))
48498b9484cSchristos 
48598b9484cSchristos # define obstack_ptr_grow_fast(h, aptr)					      \
486ba340e45Schristos   (((const void **) ((h)->next_free += sizeof (void *)))[-1] = (aptr),	      \
487ba340e45Schristos    (void) 0)
48898b9484cSchristos 
48998b9484cSchristos # define obstack_int_grow_fast(h, aint)					      \
490ba340e45Schristos   (((int *) ((h)->next_free += sizeof (int)))[-1] = (aint),		      \
491ba340e45Schristos    (void) 0)
49298b9484cSchristos 
49398b9484cSchristos # define obstack_blank(h, length)					      \
494ba340e45Schristos   ((h)->temp.i = (length),						      \
495ba340e45Schristos    ((obstack_room (h) < (h)->temp.i)					      \
496ba340e45Schristos    ? (_obstack_newchunk ((h), (h)->temp.i), 0) : 0),			      \
497ba340e45Schristos    obstack_blank_fast (h, (h)->temp.i))
49898b9484cSchristos 
49998b9484cSchristos # define obstack_alloc(h, length)					      \
50098b9484cSchristos   (obstack_blank ((h), (length)), obstack_finish ((h)))
50198b9484cSchristos 
50298b9484cSchristos # define obstack_copy(h, where, length)					      \
50398b9484cSchristos   (obstack_grow ((h), (where), (length)), obstack_finish ((h)))
50498b9484cSchristos 
50598b9484cSchristos # define obstack_copy0(h, where, length)				      \
50698b9484cSchristos   (obstack_grow0 ((h), (where), (length)), obstack_finish ((h)))
50798b9484cSchristos 
50898b9484cSchristos # define obstack_finish(h)						      \
50998b9484cSchristos   (((h)->next_free == (h)->object_base					      \
51098b9484cSchristos     ? (((h)->maybe_empty_object = 1), 0)				      \
51198b9484cSchristos     : 0),								      \
512ba340e45Schristos    (h)->temp.p = (h)->object_base,					      \
51398b9484cSchristos    (h)->next_free							      \
514ba340e45Schristos      = __PTR_ALIGN ((h)->object_base, (h)->next_free,			      \
515ba340e45Schristos                     (h)->alignment_mask),				      \
516ba340e45Schristos    (((size_t) ((h)->next_free - (char *) (h)->chunk)			      \
517ba340e45Schristos      > (size_t) ((h)->chunk_limit - (char *) (h)->chunk))		      \
51898b9484cSchristos    ? ((h)->next_free = (h)->chunk_limit) : 0),				      \
51998b9484cSchristos    (h)->object_base = (h)->next_free,					      \
520ba340e45Schristos    (h)->temp.p)
52198b9484cSchristos 
52298b9484cSchristos # define obstack_free(h, obj)						      \
523ba340e45Schristos   ((h)->temp.p = (void *) (obj),					      \
524ba340e45Schristos    (((h)->temp.p > (void *) (h)->chunk					      \
525ba340e45Schristos      && (h)->temp.p < (void *) (h)->chunk_limit)			      \
526ba340e45Schristos     ? (void) ((h)->next_free = (h)->object_base = (char *) (h)->temp.p)       \
527ba340e45Schristos     : _obstack_free ((h), (h)->temp.p)))
52898b9484cSchristos 
529ba340e45Schristos #endif /* not __GNUC__ */
53098b9484cSchristos 
53198b9484cSchristos #ifdef __cplusplus
53298b9484cSchristos }       /* C++ */
53398b9484cSchristos #endif
53498b9484cSchristos 
535ba340e45Schristos #endif /* _OBSTACK_H */
536