xref: /csrg-svn/contrib/gcc-2.3.3/obstack.h (revision 60372)
157764Selan /* obstack.h - object stack macros
257764Selan    Copyright (C) 1988, 1992 Free Software Foundation, Inc.
357764Selan 
457764Selan This program is free software; you can redistribute it and/or modify it
557764Selan under the terms of the GNU General Public License as published by the
657764Selan Free Software Foundation; either version 2, or (at your option) any
757764Selan later version.
857764Selan 
957764Selan This program is distributed in the hope that it will be useful,
1057764Selan but WITHOUT ANY WARRANTY; without even the implied warranty of
1157764Selan MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1257764Selan GNU General Public License for more details.
1357764Selan 
1457764Selan You should have received a copy of the GNU General Public License
1557764Selan along with this program; if not, write to the Free Software
1657764Selan Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
1757764Selan 
1857764Selan /* Summary:
1957764Selan 
2057764Selan All the apparent functions defined here are macros. The idea
2157764Selan is that you would use these pre-tested macros to solve a
2257764Selan very specific set of problems, and they would run fast.
2357764Selan Caution: no side-effects in arguments please!! They may be
2457764Selan evaluated MANY times!!
2557764Selan 
2657764Selan These macros operate a stack of objects.  Each object starts life
2757764Selan small, and may grow to maturity.  (Consider building a word syllable
2857764Selan by syllable.)  An object can move while it is growing.  Once it has
2957764Selan been "finished" it never changes address again.  So the "top of the
3057764Selan stack" is typically an immature growing object, while the rest of the
3157764Selan stack is of mature, fixed size and fixed address objects.
3257764Selan 
3357764Selan These routines grab large chunks of memory, using a function you
3457764Selan supply, called `obstack_chunk_alloc'.  On occasion, they free chunks,
3557764Selan by calling `obstack_chunk_free'.  You must define them and declare
3657764Selan them before using any obstack macros.
3757764Selan 
3857764Selan Each independent stack is represented by a `struct obstack'.
3957764Selan Each of the obstack macros expects a pointer to such a structure
4057764Selan as the first argument.
4157764Selan 
4257764Selan One motivation for this package is the problem of growing char strings
4357764Selan in symbol tables.  Unless you are "fascist pig with a read-only mind"
4457764Selan --Gosper's immortal quote from HAKMEM item 154, out of context--you
4557764Selan would not like to put any arbitrary upper limit on the length of your
4657764Selan symbols.
4757764Selan 
4857764Selan In practice this often means you will build many short symbols and a
4957764Selan few long symbols.  At the time you are reading a symbol you don't know
5057764Selan how long it is.  One traditional method is to read a symbol into a
5157764Selan buffer, realloc()ating the buffer every time you try to read a symbol
5257764Selan that is longer than the buffer.  This is beaut, but you still will
5357764Selan want to copy the symbol from the buffer to a more permanent
5457764Selan symbol-table entry say about half the time.
5557764Selan 
5657764Selan With obstacks, you can work differently.  Use one obstack for all symbol
5757764Selan names.  As you read a symbol, grow the name in the obstack gradually.
5857764Selan When the name is complete, finalize it.  Then, if the symbol exists already,
5957764Selan free the newly read name.
6057764Selan 
6157764Selan The way we do this is to take a large chunk, allocating memory from
6257764Selan low addresses.  When you want to build a symbol in the chunk you just
6357764Selan add chars above the current "high water mark" in the chunk.  When you
6457764Selan have finished adding chars, because you got to the end of the symbol,
6557764Selan you know how long the chars are, and you can create a new object.
6657764Selan Mostly the chars will not burst over the highest address of the chunk,
6757764Selan because you would typically expect a chunk to be (say) 100 times as
6857764Selan long as an average object.
6957764Selan 
7057764Selan In case that isn't clear, when we have enough chars to make up
7157764Selan the object, THEY ARE ALREADY CONTIGUOUS IN THE CHUNK (guaranteed)
7257764Selan so we just point to it where it lies.  No moving of chars is
7357764Selan needed and this is the second win: potentially long strings need
7457764Selan never be explicitly shuffled. Once an object is formed, it does not
7557764Selan change its address during its lifetime.
7657764Selan 
7757764Selan When the chars burst over a chunk boundary, we allocate a larger
7857764Selan chunk, and then copy the partly formed object from the end of the old
7957764Selan chunk to the beginning of the new larger chunk.  We then carry on
8057764Selan accreting characters to the end of the object as we normally would.
8157764Selan 
8257764Selan A special macro is provided to add a single char at a time to a
8357764Selan growing object.  This allows the use of register variables, which
8457764Selan break the ordinary 'growth' macro.
8557764Selan 
8657764Selan Summary:
8757764Selan 	We allocate large chunks.
8857764Selan 	We carve out one object at a time from the current chunk.
8957764Selan 	Once carved, an object never moves.
9057764Selan 	We are free to append data of any size to the currently
9157764Selan 	  growing object.
9257764Selan 	Exactly one object is growing in an obstack at any one time.
9357764Selan 	You can run one obstack per control block.
9457764Selan 	You may have as many control blocks as you dare.
9557764Selan 	Because of the way we do it, you can `unwind' an obstack
9657764Selan 	  back to a previous state. (You may remove objects much
9757764Selan 	  as you would with a stack.)
9857764Selan */
9957764Selan 
10057764Selan 
10157764Selan /* Don't do the contents of this file more than once.  */
10257764Selan 
10357764Selan #ifndef __OBSTACKS__
10457764Selan #define __OBSTACKS__
10557764Selan 
10657764Selan /* We use subtraction of (char *)0 instead of casting to int
10757764Selan    because on word-addressable machines a simple cast to int
10857764Selan    may ignore the byte-within-word field of the pointer.  */
10957764Selan 
11057764Selan #ifndef __PTR_TO_INT
11157764Selan #define __PTR_TO_INT(P) ((P) - (char *)0)
11257764Selan #endif
11357764Selan 
11457764Selan #ifndef __INT_TO_PTR
11557764Selan #define __INT_TO_PTR(P) ((P) + (char *)0)
11657764Selan #endif
11757764Selan 
11857764Selan /* We need the type of the resulting object.  In ANSI C it is ptrdiff_t
11957764Selan    but in traditional C it is usually long.  If we are in ANSI C and
12057764Selan    don't already have ptrdiff_t get it.  */
12157764Selan 
12257764Selan #if defined (__STDC__) && ! defined (offsetof)
12357764Selan #if defined (__GNUC__) && defined (IN_GCC)
12457764Selan /* On Next machine, the system's stddef.h screws up if included
12557764Selan    after we have defined just ptrdiff_t, so include all of gstddef.h.
12657764Selan    Otherwise, define just ptrdiff_t, which is all we need.  */
12757764Selan #ifndef __NeXT__
12857764Selan #define __need_ptrdiff_t
12957764Selan #endif
13057764Selan 
13157764Selan /* While building GCC, the stddef.h that goes with GCC has this name.  */
13257764Selan #include "gstddef.h"
13357764Selan #else
13457764Selan #include <stddef.h>
13557764Selan #endif
13657764Selan #endif
13757764Selan 
13857764Selan #ifdef __STDC__
139*60372Selan 
140*60372Selan 
141*60372Selan #define PTR_INT_TYPE int
14257764Selan #else
14357764Selan #define PTR_INT_TYPE long
14457764Selan #endif
14557764Selan 
14657764Selan struct _obstack_chunk		/* Lives at front of each chunk. */
14757764Selan {
14857764Selan   char  *limit;			/* 1 past end of this chunk */
14957764Selan   struct _obstack_chunk *prev;	/* address of prior chunk or NULL */
15057764Selan   char	contents[4];		/* objects begin here */
15157764Selan };
15257764Selan 
15357764Selan struct obstack		/* control current object in current chunk */
15457764Selan {
15557764Selan   long	chunk_size;		/* preferred size to allocate chunks in */
15657764Selan   struct _obstack_chunk* chunk;	/* address of current struct obstack_chunk */
15757764Selan   char	*object_base;		/* address of object we are building */
15857764Selan   char	*next_free;		/* where to add next char to current object */
15957764Selan   char	*chunk_limit;		/* address of char after current chunk */
160*60372Selan   int    temp;		/* Temporary for some macros.  */
16157764Selan   int   alignment_mask;		/* Mask of alignment for each object. */
16257764Selan   struct _obstack_chunk *(*chunkfun) (); /* User's fcn to allocate a chunk.  */
16357764Selan   void (*freefun) ();		/* User's function to free a chunk.  */
16457764Selan   char *extra_arg;		/* first arg for chunk alloc/dealloc funcs */
16557764Selan   unsigned use_extra_arg:1;	/* chunk alloc/dealloc funcs take extra arg */
16657764Selan   unsigned maybe_empty_object:1;/* There is a possibility that the current
16757764Selan 				   chunk contains a zero-length object.  This
16857764Selan 				   prevents freeing the chunk if we allocate
16957764Selan 				   a bigger chunk to replace it. */
17057764Selan };
17157764Selan 
17257764Selan /* Declare the external functions we use; they are in obstack.c.  */
17357764Selan 
17457764Selan #ifdef __STDC__
17557764Selan extern void _obstack_newchunk (struct obstack *, int);
17657764Selan extern void _obstack_free (struct obstack *, void *);
17757764Selan extern void _obstack_begin (struct obstack *, int, int,
17857764Selan 			    void *(*) (), void (*) ());
17957764Selan extern void _obstack_begin_1 (struct obstack *, int, int,
18057764Selan 			      void *(*) (), void (*) (), void *);
18157764Selan #else
18257764Selan extern void _obstack_newchunk ();
18357764Selan extern void _obstack_free ();
18457764Selan extern void _obstack_begin ();
18557764Selan extern void _obstack_begin_1 ();
18657764Selan #endif
18757764Selan 
18857764Selan #ifdef __STDC__
18957764Selan 
19057764Selan /* Do the function-declarations after the structs
19157764Selan    but before defining the macros.  */
19257764Selan 
19357764Selan void obstack_init (struct obstack *obstack);
19457764Selan 
19557764Selan void * obstack_alloc (struct obstack *obstack, int size);
19657764Selan 
19757764Selan void * obstack_copy (struct obstack *obstack, void *address, int size);
19857764Selan void * obstack_copy0 (struct obstack *obstack, void *address, int size);
19957764Selan 
20057764Selan void obstack_free (struct obstack *obstack, void *block);
20157764Selan 
20257764Selan void obstack_blank (struct obstack *obstack, int size);
20357764Selan 
20457764Selan void obstack_grow (struct obstack *obstack, void *data, int size);
20557764Selan void obstack_grow0 (struct obstack *obstack, void *data, int size);
20657764Selan 
20757764Selan void obstack_1grow (struct obstack *obstack, int data_char);
20857764Selan void obstack_ptr_grow (struct obstack *obstack, void *data);
20957764Selan void obstack_int_grow (struct obstack *obstack, int data);
21057764Selan 
21157764Selan void * obstack_finish (struct obstack *obstack);
21257764Selan 
21357764Selan int obstack_object_size (struct obstack *obstack);
21457764Selan 
21557764Selan int obstack_room (struct obstack *obstack);
21657764Selan void obstack_1grow_fast (struct obstack *obstack, int data_char);
21757764Selan void obstack_ptr_grow_fast (struct obstack *obstack, void *data);
21857764Selan void obstack_int_grow_fast (struct obstack *obstack, int data);
21957764Selan void obstack_blank_fast (struct obstack *obstack, int size);
22057764Selan 
22157764Selan void * obstack_base (struct obstack *obstack);
22257764Selan void * obstack_next_free (struct obstack *obstack);
22357764Selan int obstack_alignment_mask (struct obstack *obstack);
22457764Selan int obstack_chunk_size (struct obstack *obstack);
22557764Selan 
22657764Selan #endif /* __STDC__ */
22757764Selan 
22857764Selan /* Non-ANSI C cannot really support alternative functions for these macros,
22957764Selan    so we do not declare them.  */
23057764Selan 
23157764Selan /* Pointer to beginning of object being allocated or to be allocated next.
23257764Selan    Note that this might not be the final address of the object
23357764Selan    because a new chunk might be needed to hold the final size.  */
23457764Selan 
23557764Selan #define obstack_base(h) ((h)->object_base)
23657764Selan 
23757764Selan /* Size for allocating ordinary chunks.  */
23857764Selan 
23957764Selan #define obstack_chunk_size(h) ((h)->chunk_size)
24057764Selan 
24157764Selan /* Pointer to next byte not yet allocated in current chunk.  */
24257764Selan 
24357764Selan #define obstack_next_free(h)	((h)->next_free)
24457764Selan 
24557764Selan /* Mask specifying low bits that should be clear in address of an object.  */
24657764Selan 
24757764Selan #define obstack_alignment_mask(h) ((h)->alignment_mask)
24857764Selan 
24957764Selan #define obstack_init(h) \
25057764Selan   _obstack_begin ((h), 0, 0, \
25157764Selan 		  (void *(*) ()) obstack_chunk_alloc, (void (*) ()) obstack_chunk_free)
25257764Selan 
25357764Selan #define obstack_begin(h, size) \
25457764Selan   _obstack_begin ((h), (size), 0, \
25557764Selan 		  (void *(*) ()) obstack_chunk_alloc, (void (*) ()) obstack_chunk_free)
25657764Selan 
25757764Selan #define obstack_specify_allocation(h, size, alignment, chunkfun, freefun) \
25857764Selan   _obstack_begin ((h), (size), (alignment), \
25957764Selan 		    (void *(*) ()) (chunkfun), (void (*) ()) (freefun))
26057764Selan 
26157764Selan #define obstack_specify_allocation_with_arg(h, size, alignment, chunkfun, freefun, arg) \
26257764Selan   _obstack_begin_1 ((h), (size), (alignment), \
26357764Selan 		    (void *(*) ()) (chunkfun), (void (*) ()) (freefun), (arg))
26457764Selan 
26557764Selan #define obstack_1grow_fast(h,achar) (*((h)->next_free)++ = achar)
26657764Selan 
26757764Selan #define obstack_blank_fast(h,n) ((h)->next_free += (n))
26857764Selan 
26957764Selan #if defined (__GNUC__) && defined (__STDC__)
27057764Selan #if __GNUC__ < 2
27157764Selan #define __extension__
27257764Selan #endif
27357764Selan 
27457764Selan /* For GNU C, if not -traditional,
27557764Selan    we can define these macros to compute all args only once
27657764Selan    without using a global variable.
27757764Selan    Also, we can avoid using the `temp' slot, to make faster code.  */
27857764Selan 
27957764Selan #define obstack_object_size(OBSTACK)					\
28057764Selan   __extension__								\
28157764Selan   ({ struct obstack *__o = (OBSTACK);					\
28257764Selan      (unsigned) (__o->next_free - __o->object_base); })
28357764Selan 
28457764Selan #define obstack_room(OBSTACK)						\
28557764Selan   __extension__								\
28657764Selan   ({ struct obstack *__o = (OBSTACK);					\
28757764Selan      (unsigned) (__o->chunk_limit - __o->next_free); })
28857764Selan 
28957764Selan /* Note that the call to _obstack_newchunk is enclosed in (..., 0)
29057764Selan    so that we can avoid having void expressions
29157764Selan    in the arms of the conditional expression.
29257764Selan    Casting the third operand to void was tried before,
29357764Selan    but some compilers won't accept it.  */
29457764Selan #define obstack_grow(OBSTACK,where,length)				\
29557764Selan __extension__								\
29657764Selan ({ struct obstack *__o = (OBSTACK);					\
29757764Selan    int __len = (length);						\
29857764Selan    ((__o->next_free + __len > __o->chunk_limit)				\
29957764Selan     ? (_obstack_newchunk (__o, __len), 0) : 0);				\
30057764Selan    bcopy (where, __o->next_free, __len);				\
30157764Selan    __o->next_free += __len;						\
30257764Selan    (void) 0; })
30357764Selan 
30457764Selan #define obstack_grow0(OBSTACK,where,length)				\
30557764Selan __extension__								\
30657764Selan ({ struct obstack *__o = (OBSTACK);					\
30757764Selan    int __len = (length);						\
30857764Selan    ((__o->next_free + __len + 1 > __o->chunk_limit)			\
30957764Selan     ? (_obstack_newchunk (__o, __len + 1), 0) : 0),			\
31057764Selan    bcopy (where, __o->next_free, __len),				\
31157764Selan    __o->next_free += __len,						\
31257764Selan    *(__o->next_free)++ = 0;						\
31357764Selan    (void) 0; })
31457764Selan 
31557764Selan #define obstack_1grow(OBSTACK,datum)					\
31657764Selan __extension__								\
31757764Selan ({ struct obstack *__o = (OBSTACK);					\
31857764Selan    ((__o->next_free + 1 > __o->chunk_limit)				\
31957764Selan     ? (_obstack_newchunk (__o, 1), 0) : 0),				\
32057764Selan    *(__o->next_free)++ = (datum);					\
32157764Selan    (void) 0; })
32257764Selan 
32357764Selan /* These assume that the obstack alignment is good enough for pointers or ints,
32457764Selan    and that the data added so far to the current object
32557764Selan    shares that much alignment.  */
32657764Selan 
32757764Selan #define obstack_ptr_grow(OBSTACK,datum)					\
32857764Selan __extension__								\
32957764Selan ({ struct obstack *__o = (OBSTACK);					\
33057764Selan    ((__o->next_free + sizeof (void *) > __o->chunk_limit)		\
33157764Selan     ? (_obstack_newchunk (__o, sizeof (void *)), 0) : 0),		\
33257764Selan    *((void **)__o->next_free)++ = ((void *)datum);			\
33357764Selan    (void) 0; })
33457764Selan 
33557764Selan #define obstack_int_grow(OBSTACK,datum)					\
33657764Selan __extension__								\
33757764Selan ({ struct obstack *__o = (OBSTACK);					\
33857764Selan    ((__o->next_free + sizeof (int) > __o->chunk_limit)			\
33957764Selan     ? (_obstack_newchunk (__o, sizeof (int)), 0) : 0),			\
34057764Selan    *((int *)__o->next_free)++ = ((int)datum);				\
34157764Selan    (void) 0; })
34257764Selan 
34357764Selan #define obstack_ptr_grow_fast(h,aptr) (*((void **)(h)->next_free)++ = (void *)aptr)
34457764Selan #define obstack_int_grow_fast(h,aint) (*((int *)(h)->next_free)++ = (int)aint)
34557764Selan 
34657764Selan #define obstack_blank(OBSTACK,length)					\
34757764Selan __extension__								\
34857764Selan ({ struct obstack *__o = (OBSTACK);					\
34957764Selan    int __len = (length);						\
35057764Selan    ((__o->chunk_limit - __o->next_free < __len)				\
35157764Selan     ? (_obstack_newchunk (__o, __len), 0) : 0);				\
35257764Selan    __o->next_free += __len;						\
35357764Selan    (void) 0; })
35457764Selan 
35557764Selan #define obstack_alloc(OBSTACK,length)					\
35657764Selan __extension__								\
35757764Selan ({ struct obstack *__h = (OBSTACK);					\
35857764Selan    obstack_blank (__h, (length));					\
35957764Selan    obstack_finish (__h); })
36057764Selan 
36157764Selan #define obstack_copy(OBSTACK,where,length)				\
36257764Selan __extension__								\
36357764Selan ({ struct obstack *__h = (OBSTACK);					\
36457764Selan    obstack_grow (__h, (where), (length));				\
36557764Selan    obstack_finish (__h); })
36657764Selan 
36757764Selan #define obstack_copy0(OBSTACK,where,length)				\
36857764Selan __extension__								\
36957764Selan ({ struct obstack *__h = (OBSTACK);					\
37057764Selan    obstack_grow0 (__h, (where), (length));				\
37157764Selan    obstack_finish (__h); })
37257764Selan 
37357764Selan /* The local variable is named __o1 to avoid a name conflict
37457764Selan    when obstack_blank is called.  */
37557764Selan #define obstack_finish(OBSTACK)  					\
37657764Selan __extension__								\
37757764Selan ({ struct obstack *__o1 = (OBSTACK);					\
37857764Selan    void *value = (void *) __o1->object_base;				\
37957764Selan    if (__o1->next_free == value)					\
38057764Selan      __o1->maybe_empty_object = 1;					\
38157764Selan    __o1->next_free							\
38257764Selan      = __INT_TO_PTR ((__PTR_TO_INT (__o1->next_free)+__o1->alignment_mask)\
38357764Selan 		     & ~ (__o1->alignment_mask));			\
38457764Selan    ((__o1->next_free - (char *)__o1->chunk				\
38557764Selan      > __o1->chunk_limit - (char *)__o1->chunk)				\
38657764Selan     ? (__o1->next_free = __o1->chunk_limit) : 0);			\
38757764Selan    __o1->object_base = __o1->next_free;					\
38857764Selan    value; })
38957764Selan 
39057764Selan #define obstack_free(OBSTACK, OBJ)					\
39157764Selan __extension__								\
39257764Selan ({ struct obstack *__o = (OBSTACK);					\
39357764Selan    void *__obj = (OBJ);							\
39457764Selan    if (__obj > (void *)__o->chunk && __obj < (void *)__o->chunk_limit)  \
39557764Selan      __o->next_free = __o->object_base = __obj;				\
39657764Selan    else (obstack_free) (__o, __obj); })
39757764Selan 
39857764Selan #else /* not __GNUC__ or not __STDC__ */
39957764Selan 
40057764Selan #define obstack_object_size(h) \
40157764Selan  (unsigned) ((h)->next_free - (h)->object_base)
40257764Selan 
40357764Selan #define obstack_room(h)		\
40457764Selan  (unsigned) ((h)->chunk_limit - (h)->next_free)
40557764Selan 
40657764Selan #define obstack_grow(h,where,length)					\
40757764Selan ( (h)->temp = (length),							\
40857764Selan   (((h)->next_free + (h)->temp > (h)->chunk_limit)			\
40957764Selan    ? (_obstack_newchunk ((h), (h)->temp), 0) : 0),			\
41057764Selan   bcopy (where, (h)->next_free, (h)->temp),				\
41157764Selan   (h)->next_free += (h)->temp)
41257764Selan 
41357764Selan #define obstack_grow0(h,where,length)					\
41457764Selan ( (h)->temp = (length),							\
41557764Selan   (((h)->next_free + (h)->temp + 1 > (h)->chunk_limit)			\
41657764Selan    ? (_obstack_newchunk ((h), (h)->temp + 1), 0) : 0),			\
41757764Selan   bcopy (where, (h)->next_free, (h)->temp),				\
41857764Selan   (h)->next_free += (h)->temp,						\
41957764Selan   *((h)->next_free)++ = 0)
42057764Selan 
42157764Selan #define obstack_1grow(h,datum)						\
42257764Selan ( (((h)->next_free + 1 > (h)->chunk_limit)				\
42357764Selan    ? (_obstack_newchunk ((h), 1), 0) : 0),				\
42457764Selan   *((h)->next_free)++ = (datum))
42557764Selan 
42657764Selan #define obstack_ptr_grow(h,datum)					\
42757764Selan ( (((h)->next_free + sizeof (char *) > (h)->chunk_limit)		\
42857764Selan    ? (_obstack_newchunk ((h), sizeof (char *)), 0) : 0),		\
42957764Selan   *((char **)(((h)->next_free+=sizeof(char *))-sizeof(char *))) = ((char *)datum))
43057764Selan 
43157764Selan #define obstack_int_grow(h,datum)					\
43257764Selan ( (((h)->next_free + sizeof (int) > (h)->chunk_limit)			\
43357764Selan    ? (_obstack_newchunk ((h), sizeof (int)), 0) : 0),			\
43457764Selan   *((int *)(((h)->next_free+=sizeof(int))-sizeof(int))) = ((int)datum))
43557764Selan 
43657764Selan #define obstack_ptr_grow_fast(h,aptr) (*((char **)(h)->next_free)++ = (char *)aptr)
43757764Selan #define obstack_int_grow_fast(h,aint) (*((int *)(h)->next_free)++ = (int)aint)
43857764Selan 
43957764Selan #define obstack_blank(h,length)						\
44057764Selan ( (h)->temp = (length),							\
44157764Selan   (((h)->chunk_limit - (h)->next_free < (h)->temp)			\
44257764Selan    ? (_obstack_newchunk ((h), (h)->temp), 0) : 0),			\
44357764Selan   (h)->next_free += (h)->temp)
44457764Selan 
44557764Selan #define obstack_alloc(h,length)						\
44657764Selan  (obstack_blank ((h), (length)), obstack_finish ((h)))
44757764Selan 
44857764Selan #define obstack_copy(h,where,length)					\
44957764Selan  (obstack_grow ((h), (where), (length)), obstack_finish ((h)))
45057764Selan 
45157764Selan #define obstack_copy0(h,where,length)					\
45257764Selan  (obstack_grow0 ((h), (where), (length)), obstack_finish ((h)))
45357764Selan 
45457764Selan #define obstack_finish(h)  						\
45557764Selan ( ((h)->next_free == (h)->object_base					\
45657764Selan    ? (((h)->maybe_empty_object = 1), 0)					\
45757764Selan    : 0),								\
45857764Selan   (h)->temp = __PTR_TO_INT ((h)->object_base),				\
45957764Selan   (h)->next_free							\
46057764Selan     = __INT_TO_PTR ((__PTR_TO_INT ((h)->next_free)+(h)->alignment_mask)	\
46157764Selan 		    & ~ ((h)->alignment_mask)),				\
46257764Selan   (((h)->next_free - (char *)(h)->chunk					\
46357764Selan     > (h)->chunk_limit - (char *)(h)->chunk)				\
46457764Selan    ? ((h)->next_free = (h)->chunk_limit) : 0),				\
46557764Selan   (h)->object_base = (h)->next_free,					\
46657764Selan   __INT_TO_PTR ((h)->temp))
46757764Selan 
46857764Selan #ifdef __STDC__
46957764Selan #define obstack_free(h,obj)						\
47057764Selan ( (h)->temp = (char *)(obj) - (char *) (h)->chunk,			\
47157764Selan   (((h)->temp > 0 && (h)->temp < (h)->chunk_limit - (char *) (h)->chunk)\
47257764Selan    ? (int) ((h)->next_free = (h)->object_base				\
47357764Selan 	    = (h)->temp + (char *) (h)->chunk)				\
47457764Selan    : (((obstack_free) ((h), (h)->temp + (char *) (h)->chunk), 0), 0)))
47557764Selan #else
47657764Selan #define obstack_free(h,obj)						\
47757764Selan ( (h)->temp = (char *)(obj) - (char *) (h)->chunk,			\
47857764Selan   (((h)->temp > 0 && (h)->temp < (h)->chunk_limit - (char *) (h)->chunk)\
47957764Selan    ? (int) ((h)->next_free = (h)->object_base				\
48057764Selan 	    = (h)->temp + (char *) (h)->chunk)				\
48157764Selan    : (_obstack_free ((h), (h)->temp + (char *) (h)->chunk), 0)))
48257764Selan #endif
48357764Selan 
48457764Selan #endif /* not __GNUC__ or not __STDC__ */
48557764Selan 
48657764Selan #endif /* not __OBSTACKS__ */
487