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