1130812Smarcel/* obstack.h - object stack macros
2130812Smarcel   Copyright 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1996, 1997, 1998,
3130812Smarcel   1999, 2000
4130812Smarcel   Free Software Foundation, Inc.
5130812Smarcel
6130812Smarcel
7130812Smarcel   NOTE: The canonical source of this file is maintained with the GNU C Library.
8130812Smarcel   Bugs can be reported to bug-glibc@gnu.org.
9130812Smarcel
10130812Smarcel   This program is free software; you can redistribute it and/or modify it
11130812Smarcel   under the terms of the GNU General Public License as published by the
12130812Smarcel   Free Software Foundation; either version 2, or (at your option) any
13130812Smarcel   later version.
14130812Smarcel
15130812Smarcel   This program is distributed in the hope that it will be useful,
16130812Smarcel   but WITHOUT ANY WARRANTY; without even the implied warranty of
17130812Smarcel   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18130812Smarcel   GNU General Public License for more details.
19130812Smarcel
20130812Smarcel   You should have received a copy of the GNU General Public License
21130812Smarcel   along with this program; if not, write to the Free Software
22130812Smarcel   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
23130812Smarcel   USA.  */
24130812Smarcel
25130812Smarcel/* Summary:
26130812Smarcel
27130812SmarcelAll the apparent functions defined here are macros. The idea
28130812Smarcelis that you would use these pre-tested macros to solve a
29130812Smarcelvery specific set of problems, and they would run fast.
30130812SmarcelCaution: no side-effects in arguments please!! They may be
31130812Smarcelevaluated MANY times!!
32130812Smarcel
33130812SmarcelThese macros operate a stack of objects.  Each object starts life
34130812Smarcelsmall, and may grow to maturity.  (Consider building a word syllable
35130812Smarcelby syllable.)  An object can move while it is growing.  Once it has
36130812Smarcelbeen "finished" it never changes address again.  So the "top of the
37130812Smarcelstack" is typically an immature growing object, while the rest of the
38130812Smarcelstack is of mature, fixed size and fixed address objects.
39130812Smarcel
40130812SmarcelThese routines grab large chunks of memory, using a function you
41130812Smarcelsupply, called `obstack_chunk_alloc'.  On occasion, they free chunks,
42130812Smarcelby calling `obstack_chunk_free'.  You must define them and declare
43130812Smarcelthem before using any obstack macros.
44130812Smarcel
45130812SmarcelEach independent stack is represented by a `struct obstack'.
46130812SmarcelEach of the obstack macros expects a pointer to such a structure
47130812Smarcelas the first argument.
48130812Smarcel
49130812SmarcelOne motivation for this package is the problem of growing char strings
50130812Smarcelin symbol tables.  Unless you are "fascist pig with a read-only mind"
51130812Smarcel--Gosper's immortal quote from HAKMEM item 154, out of context--you
52130812Smarcelwould not like to put any arbitrary upper limit on the length of your
53130812Smarcelsymbols.
54130812Smarcel
55130812SmarcelIn practice this often means you will build many short symbols and a
56130812Smarcelfew long symbols.  At the time you are reading a symbol you don't know
57130812Smarcelhow long it is.  One traditional method is to read a symbol into a
58130812Smarcelbuffer, realloc()ating the buffer every time you try to read a symbol
59130812Smarcelthat is longer than the buffer.  This is beaut, but you still will
60130812Smarcelwant to copy the symbol from the buffer to a more permanent
61130812Smarcelsymbol-table entry say about half the time.
62130812Smarcel
63130812SmarcelWith obstacks, you can work differently.  Use one obstack for all symbol
64130812Smarcelnames.  As you read a symbol, grow the name in the obstack gradually.
65130812SmarcelWhen the name is complete, finalize it.  Then, if the symbol exists already,
66130812Smarcelfree the newly read name.
67130812Smarcel
68130812SmarcelThe way we do this is to take a large chunk, allocating memory from
69130812Smarcellow addresses.  When you want to build a symbol in the chunk you just
70130812Smarceladd chars above the current "high water mark" in the chunk.  When you
71130812Smarcelhave finished adding chars, because you got to the end of the symbol,
72130812Smarcelyou know how long the chars are, and you can create a new object.
73130812SmarcelMostly the chars will not burst over the highest address of the chunk,
74130812Smarcelbecause you would typically expect a chunk to be (say) 100 times as
75130812Smarcellong as an average object.
76130812Smarcel
77130812SmarcelIn case that isn't clear, when we have enough chars to make up
78130812Smarcelthe object, THEY ARE ALREADY CONTIGUOUS IN THE CHUNK (guaranteed)
79130812Smarcelso we just point to it where it lies.  No moving of chars is
80130812Smarcelneeded and this is the second win: potentially long strings need
81130812Smarcelnever be explicitly shuffled. Once an object is formed, it does not
82130812Smarcelchange its address during its lifetime.
83130812Smarcel
84130812SmarcelWhen the chars burst over a chunk boundary, we allocate a larger
85130812Smarcelchunk, and then copy the partly formed object from the end of the old
86130812Smarcelchunk to the beginning of the new larger chunk.  We then carry on
87130812Smarcelaccreting characters to the end of the object as we normally would.
88130812Smarcel
89130812SmarcelA special macro is provided to add a single char at a time to a
90130812Smarcelgrowing object.  This allows the use of register variables, which
91130812Smarcelbreak the ordinary 'growth' macro.
92130812Smarcel
93130812SmarcelSummary:
94130812Smarcel	We allocate large chunks.
95130812Smarcel	We carve out one object at a time from the current chunk.
96130812Smarcel	Once carved, an object never moves.
97130812Smarcel	We are free to append data of any size to the currently
98130812Smarcel	  growing object.
99130812Smarcel	Exactly one object is growing in an obstack at any one time.
100130812Smarcel	You can run one obstack per control block.
101130812Smarcel	You may have as many control blocks as you dare.
102130812Smarcel	Because of the way we do it, you can `unwind' an obstack
103130812Smarcel	  back to a previous state. (You may remove objects much
104130812Smarcel	  as you would with a stack.)
105130812Smarcel*/
106130812Smarcel
107130812Smarcel
108130812Smarcel/* Don't do the contents of this file more than once.  */
109130812Smarcel
110130812Smarcel#ifndef _OBSTACK_H
111130812Smarcel#define _OBSTACK_H 1
112130812Smarcel
113130812Smarcel#ifdef __cplusplus
114130812Smarcelextern "C" {
115130812Smarcel#endif
116130812Smarcel
117130812Smarcel/* We use subtraction of (char *) 0 instead of casting to int
118130812Smarcel   because on word-addressable machines a simple cast to int
119130812Smarcel   may ignore the byte-within-word field of the pointer.  */
120130812Smarcel
121130812Smarcel#ifndef __PTR_TO_INT
122130812Smarcel# define __PTR_TO_INT(P) ((P) - (char *) 0)
123130812Smarcel#endif
124130812Smarcel
125130812Smarcel#ifndef __INT_TO_PTR
126130812Smarcel# define __INT_TO_PTR(P) ((P) + (char *) 0)
127130812Smarcel#endif
128130812Smarcel
129130812Smarcel/* We need the type of the resulting object.  If __PTRDIFF_TYPE__ is
130130812Smarcel   defined, as with GNU C, use that; that way we don't pollute the
131130812Smarcel   namespace with <stddef.h>'s symbols.  Otherwise, if <stddef.h> is
132130812Smarcel   available, include it and use ptrdiff_t.  In traditional C, long is
133130812Smarcel   the best that we can do.  */
134130812Smarcel
135130812Smarcel#ifdef __PTRDIFF_TYPE__
136130812Smarcel# define PTR_INT_TYPE __PTRDIFF_TYPE__
137130812Smarcel#else
138130812Smarcel# ifdef HAVE_STDDEF_H
139130812Smarcel#  include <stddef.h>
140130812Smarcel#  define PTR_INT_TYPE ptrdiff_t
141130812Smarcel# else
142130812Smarcel#  define PTR_INT_TYPE long
143130812Smarcel# endif
144130812Smarcel#endif
145130812Smarcel
146130812Smarcel#if defined _LIBC || defined HAVE_STRING_H
147130812Smarcel# include <string.h>
148130812Smarcel# if defined __STDC__ && __STDC__
149130812Smarcel#  define _obstack_memcpy(To, From, N) memcpy ((To), (From), (N))
150130812Smarcel# else
151130812Smarcel#  define _obstack_memcpy(To, From, N) memcpy ((To), (char *)(From), (N))
152130812Smarcel# endif
153130812Smarcel#else
154130812Smarcel# ifdef memcpy
155130812Smarcel#  define _obstack_memcpy(To, From, N) memcpy ((To), (char *)(From), (N))
156130812Smarcel# else
157130812Smarcel#  define _obstack_memcpy(To, From, N) bcopy ((char *)(From), (To), (N))
158130812Smarcel# endif
159130812Smarcel#endif
160130812Smarcel
161130812Smarcelstruct _obstack_chunk		/* Lives at front of each chunk. */
162130812Smarcel{
163130812Smarcel  char  *limit;			/* 1 past end of this chunk */
164130812Smarcel  struct _obstack_chunk *prev;	/* address of prior chunk or NULL */
165130812Smarcel  char	contents[4];		/* objects begin here */
166130812Smarcel};
167130812Smarcel
168130812Smarcelstruct obstack		/* control current object in current chunk */
169130812Smarcel{
170130812Smarcel  long	chunk_size;		/* preferred size to allocate chunks in */
171130812Smarcel  struct _obstack_chunk *chunk;	/* address of current struct obstack_chunk */
172130812Smarcel  char	*object_base;		/* address of object we are building */
173130812Smarcel  char	*next_free;		/* where to add next char to current object */
174130812Smarcel  char	*chunk_limit;		/* address of char after current chunk */
175130812Smarcel  PTR_INT_TYPE temp;		/* Temporary for some macros.  */
176130812Smarcel  int   alignment_mask;		/* Mask of alignment for each object. */
177130812Smarcel#if defined __STDC__ && __STDC__
178130812Smarcel  /* These prototypes vary based on `use_extra_arg', and we use
179130812Smarcel     casts to the prototypeless function type in all assignments,
180130812Smarcel     but having prototypes here quiets -Wstrict-prototypes.  */
181130812Smarcel  struct _obstack_chunk *(*chunkfun) (void *, long);
182130812Smarcel  void (*freefun) (void *, struct _obstack_chunk *);
183130812Smarcel  void *extra_arg;		/* first arg for chunk alloc/dealloc funcs */
184130812Smarcel#else
185130812Smarcel  struct _obstack_chunk *(*chunkfun) (); /* User's fcn to allocate a chunk.  */
186130812Smarcel  void (*freefun) ();		/* User's function to free a chunk.  */
187130812Smarcel  char *extra_arg;		/* first arg for chunk alloc/dealloc funcs */
188130812Smarcel#endif
189130812Smarcel  unsigned use_extra_arg:1;	/* chunk alloc/dealloc funcs take extra arg */
190130812Smarcel  unsigned maybe_empty_object:1;/* There is a possibility that the current
191130812Smarcel				   chunk contains a zero-length object.  This
192130812Smarcel				   prevents freeing the chunk if we allocate
193130812Smarcel				   a bigger chunk to replace it. */
194130812Smarcel  unsigned alloc_failed:1;	/* No longer used, as we now call the failed
195130812Smarcel				   handler on error, but retained for binary
196130812Smarcel				   compatibility.  */
197130812Smarcel};
198130812Smarcel
199130812Smarcel/* Declare the external functions we use; they are in obstack.c.  */
200130812Smarcel
201130812Smarcel#if defined __STDC__ && __STDC__
202130812Smarcelextern void _obstack_newchunk (struct obstack *, int);
203130812Smarcelextern void _obstack_free (struct obstack *, void *);
204130812Smarcelextern int _obstack_begin (struct obstack *, int, int,
205130812Smarcel			    void *(*) (long), void (*) (void *));
206130812Smarcelextern int _obstack_begin_1 (struct obstack *, int, int,
207130812Smarcel			     void *(*) (void *, long),
208130812Smarcel			     void (*) (void *, void *), void *);
209130812Smarcelextern int _obstack_memory_used (struct obstack *);
210130812Smarcel#else
211130812Smarcelextern void _obstack_newchunk ();
212130812Smarcelextern void _obstack_free ();
213130812Smarcelextern int _obstack_begin ();
214130812Smarcelextern int _obstack_begin_1 ();
215130812Smarcelextern int _obstack_memory_used ();
216130812Smarcel#endif
217130812Smarcel
218130812Smarcel#if defined __STDC__ && __STDC__
219130812Smarcel
220130812Smarcel/* Do the function-declarations after the structs
221130812Smarcel   but before defining the macros.  */
222130812Smarcel
223130812Smarcelvoid obstack_init (struct obstack *obstack);
224130812Smarcel
225130812Smarcelvoid * obstack_alloc (struct obstack *obstack, int size);
226130812Smarcel
227130812Smarcelvoid * obstack_copy (struct obstack *obstack, void *address, int size);
228130812Smarcelvoid * obstack_copy0 (struct obstack *obstack, void *address, int size);
229130812Smarcel
230130812Smarcelvoid obstack_free (struct obstack *obstack, void *block);
231130812Smarcel
232130812Smarcelvoid obstack_blank (struct obstack *obstack, int size);
233130812Smarcel
234130812Smarcelvoid obstack_grow (struct obstack *obstack, void *data, int size);
235130812Smarcelvoid obstack_grow0 (struct obstack *obstack, void *data, int size);
236130812Smarcel
237130812Smarcelvoid obstack_1grow (struct obstack *obstack, int data_char);
238130812Smarcelvoid obstack_ptr_grow (struct obstack *obstack, void *data);
239130812Smarcelvoid obstack_int_grow (struct obstack *obstack, int data);
240130812Smarcel
241130812Smarcelvoid * obstack_finish (struct obstack *obstack);
242130812Smarcel
243130812Smarcelint obstack_object_size (struct obstack *obstack);
244130812Smarcel
245130812Smarcelint obstack_room (struct obstack *obstack);
246130812Smarcelvoid obstack_make_room (struct obstack *obstack, int size);
247130812Smarcelvoid obstack_1grow_fast (struct obstack *obstack, int data_char);
248130812Smarcelvoid obstack_ptr_grow_fast (struct obstack *obstack, void *data);
249130812Smarcelvoid obstack_int_grow_fast (struct obstack *obstack, int data);
250130812Smarcelvoid obstack_blank_fast (struct obstack *obstack, int size);
251130812Smarcel
252130812Smarcelvoid * obstack_base (struct obstack *obstack);
253130812Smarcelvoid * obstack_next_free (struct obstack *obstack);
254130812Smarcelint obstack_alignment_mask (struct obstack *obstack);
255130812Smarcelint obstack_chunk_size (struct obstack *obstack);
256130812Smarcelint obstack_memory_used (struct obstack *obstack);
257130812Smarcel
258130812Smarcel#endif /* __STDC__ */
259130812Smarcel
260130812Smarcel/* Non-ANSI C cannot really support alternative functions for these macros,
261130812Smarcel   so we do not declare them.  */
262130812Smarcel
263130812Smarcel/* Error handler called when `obstack_chunk_alloc' failed to allocate
264130812Smarcel   more memory.  This can be set to a user defined function.  The
265130812Smarcel   default action is to print a message and abort.  */
266130812Smarcel#if defined __STDC__ && __STDC__
267130812Smarcelextern void (*obstack_alloc_failed_handler) (void);
268130812Smarcel#else
269130812Smarcelextern void (*obstack_alloc_failed_handler) ();
270130812Smarcel#endif
271130812Smarcel
272130812Smarcel/* Exit value used when `print_and_abort' is used.  */
273130812Smarcelextern int obstack_exit_failure;
274130812Smarcel
275130812Smarcel/* Pointer to beginning of object being allocated or to be allocated next.
276130812Smarcel   Note that this might not be the final address of the object
277130812Smarcel   because a new chunk might be needed to hold the final size.  */
278130812Smarcel
279130812Smarcel#define obstack_base(h) ((h)->object_base)
280130812Smarcel
281130812Smarcel/* Size for allocating ordinary chunks.  */
282130812Smarcel
283130812Smarcel#define obstack_chunk_size(h) ((h)->chunk_size)
284130812Smarcel
285130812Smarcel/* Pointer to next byte not yet allocated in current chunk.  */
286130812Smarcel
287130812Smarcel#define obstack_next_free(h)	((h)->next_free)
288130812Smarcel
289130812Smarcel/* Mask specifying low bits that should be clear in address of an object.  */
290130812Smarcel
291130812Smarcel#define obstack_alignment_mask(h) ((h)->alignment_mask)
292130812Smarcel
293130812Smarcel/* To prevent prototype warnings provide complete argument list in
294130812Smarcel   standard C version.  */
295130812Smarcel#if defined __STDC__ && __STDC__
296130812Smarcel
297130812Smarcel# define obstack_init(h) \
298130812Smarcel  _obstack_begin ((h), 0, 0, \
299130812Smarcel		  (void *(*) (long)) obstack_chunk_alloc, (void (*) (void *)) obstack_chunk_free)
300130812Smarcel
301130812Smarcel# define obstack_begin(h, size) \
302130812Smarcel  _obstack_begin ((h), (size), 0, \
303130812Smarcel		  (void *(*) (long)) obstack_chunk_alloc, (void (*) (void *)) obstack_chunk_free)
304130812Smarcel
305130812Smarcel# define obstack_specify_allocation(h, size, alignment, chunkfun, freefun) \
306130812Smarcel  _obstack_begin ((h), (size), (alignment), \
307130812Smarcel		    (void *(*) (long)) (chunkfun), (void (*) (void *)) (freefun))
308130812Smarcel
309130812Smarcel# define obstack_specify_allocation_with_arg(h, size, alignment, chunkfun, freefun, arg) \
310130812Smarcel  _obstack_begin_1 ((h), (size), (alignment), \
311130812Smarcel		    (void *(*) (void *, long)) (chunkfun), \
312130812Smarcel		    (void (*) (void *, void *)) (freefun), (arg))
313130812Smarcel
314130812Smarcel# define obstack_chunkfun(h, newchunkfun) \
315130812Smarcel  ((h) -> chunkfun = (struct _obstack_chunk *(*)(void *, long)) (newchunkfun))
316130812Smarcel
317130812Smarcel# define obstack_freefun(h, newfreefun) \
318130812Smarcel  ((h) -> freefun = (void (*)(void *, struct _obstack_chunk *)) (newfreefun))
319130812Smarcel
320130812Smarcel#else
321130812Smarcel
322130812Smarcel# define obstack_init(h) \
323130812Smarcel  _obstack_begin ((h), 0, 0, \
324130812Smarcel		  (void *(*) ()) obstack_chunk_alloc, (void (*) ()) obstack_chunk_free)
325130812Smarcel
326130812Smarcel# define obstack_begin(h, size) \
327130812Smarcel  _obstack_begin ((h), (size), 0, \
328130812Smarcel		  (void *(*) ()) obstack_chunk_alloc, (void (*) ()) obstack_chunk_free)
329130812Smarcel
330130812Smarcel# define obstack_specify_allocation(h, size, alignment, chunkfun, freefun) \
331130812Smarcel  _obstack_begin ((h), (size), (alignment), \
332130812Smarcel		    (void *(*) ()) (chunkfun), (void (*) ()) (freefun))
333130812Smarcel
334130812Smarcel# define obstack_specify_allocation_with_arg(h, size, alignment, chunkfun, freefun, arg) \
335130812Smarcel  _obstack_begin_1 ((h), (size), (alignment), \
336130812Smarcel		    (void *(*) ()) (chunkfun), (void (*) ()) (freefun), (arg))
337130812Smarcel
338130812Smarcel# define obstack_chunkfun(h, newchunkfun) \
339130812Smarcel  ((h) -> chunkfun = (struct _obstack_chunk *(*)()) (newchunkfun))
340130812Smarcel
341130812Smarcel# define obstack_freefun(h, newfreefun) \
342130812Smarcel  ((h) -> freefun = (void (*)()) (newfreefun))
343130812Smarcel
344130812Smarcel#endif
345130812Smarcel
346130812Smarcel#define obstack_1grow_fast(h,achar) (*((h)->next_free)++ = (achar))
347130812Smarcel
348130812Smarcel#define obstack_blank_fast(h,n) ((h)->next_free += (n))
349130812Smarcel
350130812Smarcel#define obstack_memory_used(h) _obstack_memory_used (h)
351130812Smarcel
352130812Smarcel#if defined __GNUC__ && defined __STDC__ && __STDC__
353130812Smarcel/* NextStep 2.0 cc is really gcc 1.93 but it defines __GNUC__ = 2 and
354130812Smarcel   does not implement __extension__.  But that compiler doesn't define
355130812Smarcel   __GNUC_MINOR__.  */
356130812Smarcel# if __GNUC__ < 2 || (__NeXT__ && !__GNUC_MINOR__)
357130812Smarcel#  define __extension__
358130812Smarcel# endif
359130812Smarcel
360130812Smarcel/* For GNU C, if not -traditional,
361130812Smarcel   we can define these macros to compute all args only once
362130812Smarcel   without using a global variable.
363130812Smarcel   Also, we can avoid using the `temp' slot, to make faster code.  */
364130812Smarcel
365130812Smarcel# define obstack_object_size(OBSTACK)					\
366130812Smarcel  __extension__								\
367130812Smarcel  ({ struct obstack *__o = (OBSTACK);					\
368130812Smarcel     (unsigned) (__o->next_free - __o->object_base); })
369130812Smarcel
370130812Smarcel# define obstack_room(OBSTACK)						\
371130812Smarcel  __extension__								\
372130812Smarcel  ({ struct obstack *__o = (OBSTACK);					\
373130812Smarcel     (unsigned) (__o->chunk_limit - __o->next_free); })
374130812Smarcel
375130812Smarcel# define obstack_make_room(OBSTACK,length)				\
376130812Smarcel__extension__								\
377130812Smarcel({ struct obstack *__o = (OBSTACK);					\
378130812Smarcel   int __len = (length);						\
379130812Smarcel   if (__o->chunk_limit - __o->next_free < __len)			\
380130812Smarcel     _obstack_newchunk (__o, __len);					\
381130812Smarcel   (void) 0; })
382130812Smarcel
383130812Smarcel# define obstack_empty_p(OBSTACK)					\
384130812Smarcel  __extension__								\
385130812Smarcel  ({ struct obstack *__o = (OBSTACK);					\
386130812Smarcel     (__o->chunk->prev == 0 && __o->next_free - __o->chunk->contents == 0); })
387130812Smarcel
388130812Smarcel# define obstack_grow(OBSTACK,where,length)				\
389130812Smarcel__extension__								\
390130812Smarcel({ struct obstack *__o = (OBSTACK);					\
391130812Smarcel   int __len = (length);						\
392130812Smarcel   if (__o->next_free + __len > __o->chunk_limit)			\
393130812Smarcel     _obstack_newchunk (__o, __len);					\
394130812Smarcel   _obstack_memcpy (__o->next_free, (where), __len);			\
395130812Smarcel   __o->next_free += __len;						\
396130812Smarcel   (void) 0; })
397130812Smarcel
398130812Smarcel# define obstack_grow0(OBSTACK,where,length)				\
399130812Smarcel__extension__								\
400130812Smarcel({ struct obstack *__o = (OBSTACK);					\
401130812Smarcel   int __len = (length);						\
402130812Smarcel   if (__o->next_free + __len + 1 > __o->chunk_limit)			\
403130812Smarcel     _obstack_newchunk (__o, __len + 1);				\
404130812Smarcel   _obstack_memcpy (__o->next_free, (where), __len);			\
405130812Smarcel   __o->next_free += __len;						\
406130812Smarcel   *(__o->next_free)++ = 0;						\
407130812Smarcel   (void) 0; })
408130812Smarcel
409130812Smarcel# define obstack_1grow(OBSTACK,datum)					\
410130812Smarcel__extension__								\
411130812Smarcel({ struct obstack *__o = (OBSTACK);					\
412130812Smarcel   if (__o->next_free + 1 > __o->chunk_limit)				\
413130812Smarcel     _obstack_newchunk (__o, 1);					\
414130812Smarcel   obstack_1grow_fast (__o, datum);					\
415130812Smarcel   (void) 0; })
416130812Smarcel
417130812Smarcel/* These assume that the obstack alignment is good enough for pointers or ints,
418130812Smarcel   and that the data added so far to the current object
419130812Smarcel   shares that much alignment.  */
420130812Smarcel
421130812Smarcel# define obstack_ptr_grow(OBSTACK,datum)				\
422130812Smarcel__extension__								\
423130812Smarcel({ struct obstack *__o = (OBSTACK);					\
424130812Smarcel   if (__o->next_free + sizeof (void *) > __o->chunk_limit)		\
425130812Smarcel     _obstack_newchunk (__o, sizeof (void *));				\
426130812Smarcel   obstack_ptr_grow_fast (__o, datum); })
427130812Smarcel
428130812Smarcel# define obstack_int_grow(OBSTACK,datum)				\
429130812Smarcel__extension__								\
430130812Smarcel({ struct obstack *__o = (OBSTACK);					\
431130812Smarcel   if (__o->next_free + sizeof (int) > __o->chunk_limit)		\
432130812Smarcel     _obstack_newchunk (__o, sizeof (int));				\
433130812Smarcel   obstack_int_grow_fast (__o, datum); })
434130812Smarcel
435130812Smarcel# define obstack_ptr_grow_fast(OBSTACK,aptr)				\
436130812Smarcel__extension__								\
437130812Smarcel({ struct obstack *__o1 = (OBSTACK);					\
438130812Smarcel   *(const void **) __o1->next_free = (aptr);				\
439130812Smarcel   __o1->next_free += sizeof (const void *);				\
440130812Smarcel   (void) 0; })
441130812Smarcel
442130812Smarcel# define obstack_int_grow_fast(OBSTACK,aint)				\
443130812Smarcel__extension__								\
444130812Smarcel({ struct obstack *__o1 = (OBSTACK);					\
445130812Smarcel   *(int *) __o1->next_free = (aint);					\
446130812Smarcel   __o1->next_free += sizeof (int);					\
447130812Smarcel   (void) 0; })
448130812Smarcel
449130812Smarcel# define obstack_blank(OBSTACK,length)					\
450130812Smarcel__extension__								\
451130812Smarcel({ struct obstack *__o = (OBSTACK);					\
452130812Smarcel   int __len = (length);						\
453130812Smarcel   if (__o->chunk_limit - __o->next_free < __len)			\
454130812Smarcel     _obstack_newchunk (__o, __len);					\
455130812Smarcel   obstack_blank_fast (__o, __len);					\
456130812Smarcel   (void) 0; })
457130812Smarcel
458130812Smarcel# define obstack_alloc(OBSTACK,length)					\
459130812Smarcel__extension__								\
460130812Smarcel({ struct obstack *__h = (OBSTACK);					\
461130812Smarcel   obstack_blank (__h, (length));					\
462130812Smarcel   obstack_finish (__h); })
463130812Smarcel
464130812Smarcel# define obstack_copy(OBSTACK,where,length)				\
465130812Smarcel__extension__								\
466130812Smarcel({ struct obstack *__h = (OBSTACK);					\
467130812Smarcel   obstack_grow (__h, (where), (length));				\
468130812Smarcel   obstack_finish (__h); })
469130812Smarcel
470130812Smarcel# define obstack_copy0(OBSTACK,where,length)				\
471130812Smarcel__extension__								\
472130812Smarcel({ struct obstack *__h = (OBSTACK);					\
473130812Smarcel   obstack_grow0 (__h, (where), (length));				\
474130812Smarcel   obstack_finish (__h); })
475130812Smarcel
476130812Smarcel/* The local variable is named __o1 to avoid a name conflict
477130812Smarcel   when obstack_blank is called.  */
478130812Smarcel# define obstack_finish(OBSTACK)  					\
479130812Smarcel__extension__								\
480130812Smarcel({ struct obstack *__o1 = (OBSTACK);					\
481130812Smarcel   void *value;								\
482130812Smarcel   value = (void *) __o1->object_base;					\
483130812Smarcel   if (__o1->next_free == value)					\
484130812Smarcel     __o1->maybe_empty_object = 1;					\
485130812Smarcel   __o1->next_free							\
486130812Smarcel     = __INT_TO_PTR ((__PTR_TO_INT (__o1->next_free)+__o1->alignment_mask)\
487130812Smarcel		     & ~ (__o1->alignment_mask));			\
488130812Smarcel   if (__o1->next_free - (char *)__o1->chunk				\
489130812Smarcel       > __o1->chunk_limit - (char *)__o1->chunk)			\
490130812Smarcel     __o1->next_free = __o1->chunk_limit;				\
491130812Smarcel   __o1->object_base = __o1->next_free;					\
492130812Smarcel   value; })
493130812Smarcel
494130812Smarcel# define obstack_free(OBSTACK, OBJ)					\
495130812Smarcel__extension__								\
496130812Smarcel({ struct obstack *__o = (OBSTACK);					\
497130812Smarcel   void *__obj = (OBJ);							\
498130812Smarcel   if (__obj > (void *)__o->chunk && __obj < (void *)__o->chunk_limit)  \
499130812Smarcel     __o->next_free = __o->object_base = __obj;				\
500130812Smarcel   else (obstack_free) (__o, __obj); })
501130812Smarcel
502130812Smarcel#else /* not __GNUC__ or not __STDC__ */
503130812Smarcel
504130812Smarcel# define obstack_object_size(h) \
505130812Smarcel (unsigned) ((h)->next_free - (h)->object_base)
506130812Smarcel
507130812Smarcel# define obstack_room(h)		\
508130812Smarcel (unsigned) ((h)->chunk_limit - (h)->next_free)
509130812Smarcel
510130812Smarcel# define obstack_empty_p(h) \
511130812Smarcel ((h)->chunk->prev == 0 && (h)->next_free - (h)->chunk->contents == 0)
512130812Smarcel
513130812Smarcel/* Note that the call to _obstack_newchunk is enclosed in (..., 0)
514130812Smarcel   so that we can avoid having void expressions
515130812Smarcel   in the arms of the conditional expression.
516130812Smarcel   Casting the third operand to void was tried before,
517130812Smarcel   but some compilers won't accept it.  */
518130812Smarcel
519130812Smarcel# define obstack_make_room(h,length)					\
520130812Smarcel( (h)->temp = (length),							\
521130812Smarcel  (((h)->next_free + (h)->temp > (h)->chunk_limit)			\
522130812Smarcel   ? (_obstack_newchunk ((h), (h)->temp), 0) : 0))
523130812Smarcel
524130812Smarcel# define obstack_grow(h,where,length)					\
525130812Smarcel( (h)->temp = (length),							\
526130812Smarcel  (((h)->next_free + (h)->temp > (h)->chunk_limit)			\
527130812Smarcel   ? (_obstack_newchunk ((h), (h)->temp), 0) : 0),			\
528130812Smarcel  _obstack_memcpy ((h)->next_free, (where), (h)->temp),			\
529130812Smarcel  (h)->next_free += (h)->temp)
530130812Smarcel
531130812Smarcel# define obstack_grow0(h,where,length)					\
532130812Smarcel( (h)->temp = (length),							\
533130812Smarcel  (((h)->next_free + (h)->temp + 1 > (h)->chunk_limit)			\
534130812Smarcel   ? (_obstack_newchunk ((h), (h)->temp + 1), 0) : 0),			\
535130812Smarcel  _obstack_memcpy ((h)->next_free, (where), (h)->temp),			\
536130812Smarcel  (h)->next_free += (h)->temp,						\
537130812Smarcel  *((h)->next_free)++ = 0)
538130812Smarcel
539130812Smarcel# define obstack_1grow(h,datum)						\
540130812Smarcel( (((h)->next_free + 1 > (h)->chunk_limit)				\
541130812Smarcel   ? (_obstack_newchunk ((h), 1), 0) : 0),				\
542130812Smarcel  obstack_1grow_fast (h, datum))
543130812Smarcel
544130812Smarcel# define obstack_ptr_grow(h,datum)					\
545130812Smarcel( (((h)->next_free + sizeof (char *) > (h)->chunk_limit)		\
546130812Smarcel   ? (_obstack_newchunk ((h), sizeof (char *)), 0) : 0),		\
547130812Smarcel  obstack_ptr_grow_fast (h, datum))
548130812Smarcel
549130812Smarcel# define obstack_int_grow(h,datum)					\
550130812Smarcel( (((h)->next_free + sizeof (int) > (h)->chunk_limit)			\
551130812Smarcel   ? (_obstack_newchunk ((h), sizeof (int)), 0) : 0),			\
552130812Smarcel  obstack_int_grow_fast (h, datum))
553130812Smarcel
554130812Smarcel# define obstack_ptr_grow_fast(h,aptr)					\
555130812Smarcel  (((const void **) ((h)->next_free += sizeof (void *)))[-1] = (aptr))
556130812Smarcel
557130812Smarcel# define obstack_int_grow_fast(h,aint)					\
558130812Smarcel  (((int *) ((h)->next_free += sizeof (int)))[-1] = (aptr))
559130812Smarcel
560130812Smarcel# define obstack_blank(h,length)					\
561130812Smarcel( (h)->temp = (length),							\
562130812Smarcel  (((h)->chunk_limit - (h)->next_free < (h)->temp)			\
563130812Smarcel   ? (_obstack_newchunk ((h), (h)->temp), 0) : 0),			\
564130812Smarcel  obstack_blank_fast (h, (h)->temp))
565130812Smarcel
566130812Smarcel# define obstack_alloc(h,length)					\
567130812Smarcel (obstack_blank ((h), (length)), obstack_finish ((h)))
568130812Smarcel
569130812Smarcel# define obstack_copy(h,where,length)					\
570130812Smarcel (obstack_grow ((h), (where), (length)), obstack_finish ((h)))
571130812Smarcel
572130812Smarcel# define obstack_copy0(h,where,length)					\
573130812Smarcel (obstack_grow0 ((h), (where), (length)), obstack_finish ((h)))
574130812Smarcel
575130812Smarcel# define obstack_finish(h)  						\
576130812Smarcel( ((h)->next_free == (h)->object_base					\
577130812Smarcel   ? (((h)->maybe_empty_object = 1), 0)					\
578130812Smarcel   : 0),								\
579130812Smarcel  (h)->temp = __PTR_TO_INT ((h)->object_base),				\
580130812Smarcel  (h)->next_free							\
581130812Smarcel    = __INT_TO_PTR ((__PTR_TO_INT ((h)->next_free)+(h)->alignment_mask)	\
582130812Smarcel		    & ~ ((h)->alignment_mask)),				\
583130812Smarcel  (((h)->next_free - (char *) (h)->chunk				\
584130812Smarcel    > (h)->chunk_limit - (char *) (h)->chunk)				\
585130812Smarcel   ? ((h)->next_free = (h)->chunk_limit) : 0),				\
586130812Smarcel  (h)->object_base = (h)->next_free,					\
587130812Smarcel  __INT_TO_PTR ((h)->temp))
588130812Smarcel
589130812Smarcel# if defined __STDC__ && __STDC__
590130812Smarcel#  define obstack_free(h,obj)						\
591130812Smarcel( (h)->temp = (char *) (obj) - (char *) (h)->chunk,			\
592130812Smarcel  (((h)->temp > 0 && (h)->temp < (h)->chunk_limit - (char *) (h)->chunk)\
593130812Smarcel   ? (int) ((h)->next_free = (h)->object_base				\
594130812Smarcel	    = (h)->temp + (char *) (h)->chunk)				\
595130812Smarcel   : (((obstack_free) ((h), (h)->temp + (char *) (h)->chunk), 0), 0)))
596130812Smarcel# else
597130812Smarcel#  define obstack_free(h,obj)						\
598130812Smarcel( (h)->temp = (char *) (obj) - (char *) (h)->chunk,			\
599130812Smarcel  (((h)->temp > 0 && (h)->temp < (h)->chunk_limit - (char *) (h)->chunk)\
600130812Smarcel   ? (int) ((h)->next_free = (h)->object_base				\
601130812Smarcel	    = (h)->temp + (char *) (h)->chunk)				\
602130812Smarcel   : (_obstack_free ((h), (h)->temp + (char *) (h)->chunk), 0)))
603130812Smarcel# endif
604130812Smarcel
605130812Smarcel#endif /* not __GNUC__ or not __STDC__ */
606130812Smarcel
607130812Smarcel#ifdef __cplusplus
608130812Smarcel}	/* C++ */
609130812Smarcel#endif
610130812Smarcel
611130812Smarcel#endif /* obstack.h */
612