1*53ee8cc1Swenshuai.xi /* obstack.h - object stack macros 2*53ee8cc1Swenshuai.xi Copyright (C) 1988-1994,1996-1999,2003,2004,2005 3*53ee8cc1Swenshuai.xi Free Software Foundation, Inc. 4*53ee8cc1Swenshuai.xi This file is part of the GNU C Library. 5*53ee8cc1Swenshuai.xi 6*53ee8cc1Swenshuai.xi The GNU C Library is free software; you can redistribute it and/or 7*53ee8cc1Swenshuai.xi modify it under the terms of the GNU Lesser General Public 8*53ee8cc1Swenshuai.xi License as published by the Free Software Foundation; either 9*53ee8cc1Swenshuai.xi version 2.1 of the License, or (at your option) any later version. 10*53ee8cc1Swenshuai.xi 11*53ee8cc1Swenshuai.xi The GNU C Library is distributed in the hope that it will be useful, 12*53ee8cc1Swenshuai.xi but WITHOUT ANY WARRANTY; without even the implied warranty of 13*53ee8cc1Swenshuai.xi MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14*53ee8cc1Swenshuai.xi Lesser General Public License for more details. 15*53ee8cc1Swenshuai.xi 16*53ee8cc1Swenshuai.xi You should have received a copy of the GNU Lesser General Public 17*53ee8cc1Swenshuai.xi License along with the GNU C Library; if not, write to the Free 18*53ee8cc1Swenshuai.xi Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 19*53ee8cc1Swenshuai.xi Boston, MA 02110-1301, USA. */ 20*53ee8cc1Swenshuai.xi 21*53ee8cc1Swenshuai.xi /* Summary: 22*53ee8cc1Swenshuai.xi 23*53ee8cc1Swenshuai.xi All the apparent functions defined here are macros. The idea 24*53ee8cc1Swenshuai.xi is that you would use these pre-tested macros to solve a 25*53ee8cc1Swenshuai.xi very specific set of problems, and they would run fast. 26*53ee8cc1Swenshuai.xi Caution: no side-effects in arguments please!! They may be 27*53ee8cc1Swenshuai.xi evaluated MANY times!! 28*53ee8cc1Swenshuai.xi 29*53ee8cc1Swenshuai.xi These macros operate a stack of objects. Each object starts life 30*53ee8cc1Swenshuai.xi small, and may grow to maturity. (Consider building a word syllable 31*53ee8cc1Swenshuai.xi by syllable.) An object can move while it is growing. Once it has 32*53ee8cc1Swenshuai.xi been "finished" it never changes address again. So the "top of the 33*53ee8cc1Swenshuai.xi stack" is typically an immature growing object, while the rest of the 34*53ee8cc1Swenshuai.xi stack is of mature, fixed size and fixed address objects. 35*53ee8cc1Swenshuai.xi 36*53ee8cc1Swenshuai.xi These routines grab large chunks of memory, using a function you 37*53ee8cc1Swenshuai.xi supply, called `obstack_chunk_alloc'. On occasion, they free chunks, 38*53ee8cc1Swenshuai.xi by calling `obstack_chunk_free'. You must define them and declare 39*53ee8cc1Swenshuai.xi them before using any obstack macros. 40*53ee8cc1Swenshuai.xi 41*53ee8cc1Swenshuai.xi Each independent stack is represented by a `struct obstack'. 42*53ee8cc1Swenshuai.xi Each of the obstack macros expects a pointer to such a structure 43*53ee8cc1Swenshuai.xi as the first argument. 44*53ee8cc1Swenshuai.xi 45*53ee8cc1Swenshuai.xi One motivation for this package is the problem of growing char strings 46*53ee8cc1Swenshuai.xi in symbol tables. Unless you are "fascist pig with a read-only mind" 47*53ee8cc1Swenshuai.xi --Gosper's immortal quote from HAKMEM item 154, out of context--you 48*53ee8cc1Swenshuai.xi would not like to put any arbitrary upper limit on the length of your 49*53ee8cc1Swenshuai.xi symbols. 50*53ee8cc1Swenshuai.xi 51*53ee8cc1Swenshuai.xi In practice this often means you will build many short symbols and a 52*53ee8cc1Swenshuai.xi few long symbols. At the time you are reading a symbol you don't know 53*53ee8cc1Swenshuai.xi how long it is. One traditional method is to read a symbol into a 54*53ee8cc1Swenshuai.xi buffer, realloc()ating the buffer every time you try to read a symbol 55*53ee8cc1Swenshuai.xi that is longer than the buffer. This is beaut, but you still will 56*53ee8cc1Swenshuai.xi want to copy the symbol from the buffer to a more permanent 57*53ee8cc1Swenshuai.xi symbol-table entry say about half the time. 58*53ee8cc1Swenshuai.xi 59*53ee8cc1Swenshuai.xi With obstacks, you can work differently. Use one obstack for all symbol 60*53ee8cc1Swenshuai.xi names. As you read a symbol, grow the name in the obstack gradually. 61*53ee8cc1Swenshuai.xi When the name is complete, finalize it. Then, if the symbol exists already, 62*53ee8cc1Swenshuai.xi free the newly read name. 63*53ee8cc1Swenshuai.xi 64*53ee8cc1Swenshuai.xi The way we do this is to take a large chunk, allocating memory from 65*53ee8cc1Swenshuai.xi low addresses. When you want to build a symbol in the chunk you just 66*53ee8cc1Swenshuai.xi add chars above the current "high water mark" in the chunk. When you 67*53ee8cc1Swenshuai.xi have finished adding chars, because you got to the end of the symbol, 68*53ee8cc1Swenshuai.xi you know how long the chars are, and you can create a new object. 69*53ee8cc1Swenshuai.xi Mostly the chars will not burst over the highest address of the chunk, 70*53ee8cc1Swenshuai.xi because you would typically expect a chunk to be (say) 100 times as 71*53ee8cc1Swenshuai.xi long as an average object. 72*53ee8cc1Swenshuai.xi 73*53ee8cc1Swenshuai.xi In case that isn't clear, when we have enough chars to make up 74*53ee8cc1Swenshuai.xi the object, THEY ARE ALREADY CONTIGUOUS IN THE CHUNK (guaranteed) 75*53ee8cc1Swenshuai.xi so we just point to it where it lies. No moving of chars is 76*53ee8cc1Swenshuai.xi needed and this is the second win: potentially long strings need 77*53ee8cc1Swenshuai.xi never be explicitly shuffled. Once an object is formed, it does not 78*53ee8cc1Swenshuai.xi change its address during its lifetime. 79*53ee8cc1Swenshuai.xi 80*53ee8cc1Swenshuai.xi When the chars burst over a chunk boundary, we allocate a larger 81*53ee8cc1Swenshuai.xi chunk, and then copy the partly formed object from the end of the old 82*53ee8cc1Swenshuai.xi chunk to the beginning of the new larger chunk. We then carry on 83*53ee8cc1Swenshuai.xi accreting characters to the end of the object as we normally would. 84*53ee8cc1Swenshuai.xi 85*53ee8cc1Swenshuai.xi A special macro is provided to add a single char at a time to a 86*53ee8cc1Swenshuai.xi growing object. This allows the use of register variables, which 87*53ee8cc1Swenshuai.xi break the ordinary 'growth' macro. 88*53ee8cc1Swenshuai.xi 89*53ee8cc1Swenshuai.xi Summary: 90*53ee8cc1Swenshuai.xi We allocate large chunks. 91*53ee8cc1Swenshuai.xi We carve out one object at a time from the current chunk. 92*53ee8cc1Swenshuai.xi Once carved, an object never moves. 93*53ee8cc1Swenshuai.xi We are free to append data of any size to the currently 94*53ee8cc1Swenshuai.xi growing object. 95*53ee8cc1Swenshuai.xi Exactly one object is growing in an obstack at any one time. 96*53ee8cc1Swenshuai.xi You can run one obstack per control block. 97*53ee8cc1Swenshuai.xi You may have as many control blocks as you dare. 98*53ee8cc1Swenshuai.xi Because of the way we do it, you can `unwind' an obstack 99*53ee8cc1Swenshuai.xi back to a previous state. (You may remove objects much 100*53ee8cc1Swenshuai.xi as you would with a stack.) 101*53ee8cc1Swenshuai.xi */ 102*53ee8cc1Swenshuai.xi 103*53ee8cc1Swenshuai.xi 104*53ee8cc1Swenshuai.xi /* Don't do the contents of this file more than once. */ 105*53ee8cc1Swenshuai.xi 106*53ee8cc1Swenshuai.xi #ifndef _OBSTACK_H 107*53ee8cc1Swenshuai.xi #define _OBSTACK_H 1 108*53ee8cc1Swenshuai.xi 109*53ee8cc1Swenshuai.xi #ifdef __cplusplus 110*53ee8cc1Swenshuai.xi extern "C" { 111*53ee8cc1Swenshuai.xi #endif 112*53ee8cc1Swenshuai.xi 113*53ee8cc1Swenshuai.xi /* We need the type of a pointer subtraction. If __PTRDIFF_TYPE__ is 114*53ee8cc1Swenshuai.xi defined, as with GNU C, use that; that way we don't pollute the 115*53ee8cc1Swenshuai.xi namespace with <stddef.h>'s symbols. Otherwise, include <stddef.h> 116*53ee8cc1Swenshuai.xi and use ptrdiff_t. */ 117*53ee8cc1Swenshuai.xi 118*53ee8cc1Swenshuai.xi #ifdef __PTRDIFF_TYPE__ 119*53ee8cc1Swenshuai.xi # define PTR_INT_TYPE __PTRDIFF_TYPE__ 120*53ee8cc1Swenshuai.xi #else 121*53ee8cc1Swenshuai.xi # include <stddef.h> 122*53ee8cc1Swenshuai.xi # define PTR_INT_TYPE ptrdiff_t 123*53ee8cc1Swenshuai.xi #endif 124*53ee8cc1Swenshuai.xi 125*53ee8cc1Swenshuai.xi /* If B is the base of an object addressed by P, return the result of 126*53ee8cc1Swenshuai.xi aligning P to the next multiple of A + 1. B and P must be of type 127*53ee8cc1Swenshuai.xi char *. A + 1 must be a power of 2. */ 128*53ee8cc1Swenshuai.xi 129*53ee8cc1Swenshuai.xi #define __BPTR_ALIGN(B, P, A) ((B) + (((P) - (B) + (A)) & ~(A))) 130*53ee8cc1Swenshuai.xi 131*53ee8cc1Swenshuai.xi /* Similiar to _BPTR_ALIGN (B, P, A), except optimize the common case 132*53ee8cc1Swenshuai.xi where pointers can be converted to integers, aligned as integers, 133*53ee8cc1Swenshuai.xi and converted back again. If PTR_INT_TYPE is narrower than a 134*53ee8cc1Swenshuai.xi pointer (e.g., the AS/400), play it safe and compute the alignment 135*53ee8cc1Swenshuai.xi relative to B. Otherwise, use the faster strategy of computing the 136*53ee8cc1Swenshuai.xi alignment relative to 0. */ 137*53ee8cc1Swenshuai.xi 138*53ee8cc1Swenshuai.xi #define __PTR_ALIGN(B, P, A) \ 139*53ee8cc1Swenshuai.xi __BPTR_ALIGN (sizeof (PTR_INT_TYPE) < sizeof (void *) ? (B) : (char *) 0, \ 140*53ee8cc1Swenshuai.xi P, A) 141*53ee8cc1Swenshuai.xi 142*53ee8cc1Swenshuai.xi #include <string.h> 143*53ee8cc1Swenshuai.xi 144*53ee8cc1Swenshuai.xi struct _obstack_chunk /* Lives at front of each chunk. */ 145*53ee8cc1Swenshuai.xi { 146*53ee8cc1Swenshuai.xi char *limit; /* 1 past end of this chunk */ 147*53ee8cc1Swenshuai.xi struct _obstack_chunk *prev; /* address of prior chunk or NULL */ 148*53ee8cc1Swenshuai.xi char contents[4]; /* objects begin here */ 149*53ee8cc1Swenshuai.xi }; 150*53ee8cc1Swenshuai.xi 151*53ee8cc1Swenshuai.xi struct obstack /* control current object in current chunk */ 152*53ee8cc1Swenshuai.xi { 153*53ee8cc1Swenshuai.xi long chunk_size; /* preferred size to allocate chunks in */ 154*53ee8cc1Swenshuai.xi struct _obstack_chunk *chunk; /* address of current struct obstack_chunk */ 155*53ee8cc1Swenshuai.xi char *object_base; /* address of object we are building */ 156*53ee8cc1Swenshuai.xi char *next_free; /* where to add next char to current object */ 157*53ee8cc1Swenshuai.xi char *chunk_limit; /* address of char after current chunk */ 158*53ee8cc1Swenshuai.xi union 159*53ee8cc1Swenshuai.xi { 160*53ee8cc1Swenshuai.xi PTR_INT_TYPE tempint; 161*53ee8cc1Swenshuai.xi void *tempptr; 162*53ee8cc1Swenshuai.xi } temp; /* Temporary for some macros. */ 163*53ee8cc1Swenshuai.xi int alignment_mask; /* Mask of alignment for each object. */ 164*53ee8cc1Swenshuai.xi /* These prototypes vary based on `use_extra_arg', and we use 165*53ee8cc1Swenshuai.xi casts to the prototypeless function type in all assignments, 166*53ee8cc1Swenshuai.xi but having prototypes here quiets -Wstrict-prototypes. */ 167*53ee8cc1Swenshuai.xi struct _obstack_chunk *(*chunkfun) (void *, long); 168*53ee8cc1Swenshuai.xi void (*freefun) (void *, struct _obstack_chunk *); 169*53ee8cc1Swenshuai.xi void *extra_arg; /* first arg for chunk alloc/dealloc funcs */ 170*53ee8cc1Swenshuai.xi unsigned use_extra_arg:1; /* chunk alloc/dealloc funcs take extra arg */ 171*53ee8cc1Swenshuai.xi unsigned maybe_empty_object:1;/* There is a possibility that the current 172*53ee8cc1Swenshuai.xi chunk contains a zero-length object. This 173*53ee8cc1Swenshuai.xi prevents freeing the chunk if we allocate 174*53ee8cc1Swenshuai.xi a bigger chunk to replace it. */ 175*53ee8cc1Swenshuai.xi unsigned alloc_failed:1; /* No longer used, as we now call the failed 176*53ee8cc1Swenshuai.xi handler on error, but retained for binary 177*53ee8cc1Swenshuai.xi compatibility. */ 178*53ee8cc1Swenshuai.xi }; 179*53ee8cc1Swenshuai.xi 180*53ee8cc1Swenshuai.xi /* Declare the external functions we use; they are in obstack.c. */ 181*53ee8cc1Swenshuai.xi 182*53ee8cc1Swenshuai.xi extern void _obstack_newchunk (struct obstack *, int); 183*53ee8cc1Swenshuai.xi extern int _obstack_begin (struct obstack *, int, int, 184*53ee8cc1Swenshuai.xi void *(*) (long), void (*) (void *)); 185*53ee8cc1Swenshuai.xi extern int _obstack_begin_1 (struct obstack *, int, int, 186*53ee8cc1Swenshuai.xi void *(*) (void *, long), 187*53ee8cc1Swenshuai.xi void (*) (void *, void *), void *); 188*53ee8cc1Swenshuai.xi extern int _obstack_memory_used (struct obstack *); 189*53ee8cc1Swenshuai.xi 190*53ee8cc1Swenshuai.xi void obstack_free (struct obstack *obstack, void *block); 191*53ee8cc1Swenshuai.xi 192*53ee8cc1Swenshuai.xi 193*53ee8cc1Swenshuai.xi /* Error handler called when `obstack_chunk_alloc' failed to allocate 194*53ee8cc1Swenshuai.xi more memory. This can be set to a user defined function which 195*53ee8cc1Swenshuai.xi should either abort gracefully or use longjump - but shouldn't 196*53ee8cc1Swenshuai.xi return. The default action is to print a message and abort. */ 197*53ee8cc1Swenshuai.xi extern void (*obstack_alloc_failed_handler) (void); 198*53ee8cc1Swenshuai.xi 199*53ee8cc1Swenshuai.xi /* Exit value used when `print_and_abort' is used. */ 200*53ee8cc1Swenshuai.xi extern int obstack_exit_failure; 201*53ee8cc1Swenshuai.xi 202*53ee8cc1Swenshuai.xi /* Pointer to beginning of object being allocated or to be allocated next. 203*53ee8cc1Swenshuai.xi Note that this might not be the final address of the object 204*53ee8cc1Swenshuai.xi because a new chunk might be needed to hold the final size. */ 205*53ee8cc1Swenshuai.xi 206*53ee8cc1Swenshuai.xi #define obstack_base(h) ((void *) (h)->object_base) 207*53ee8cc1Swenshuai.xi 208*53ee8cc1Swenshuai.xi /* Size for allocating ordinary chunks. */ 209*53ee8cc1Swenshuai.xi 210*53ee8cc1Swenshuai.xi #define obstack_chunk_size(h) ((h)->chunk_size) 211*53ee8cc1Swenshuai.xi 212*53ee8cc1Swenshuai.xi /* Pointer to next byte not yet allocated in current chunk. */ 213*53ee8cc1Swenshuai.xi 214*53ee8cc1Swenshuai.xi #define obstack_next_free(h) ((h)->next_free) 215*53ee8cc1Swenshuai.xi 216*53ee8cc1Swenshuai.xi /* Mask specifying low bits that should be clear in address of an object. */ 217*53ee8cc1Swenshuai.xi 218*53ee8cc1Swenshuai.xi #define obstack_alignment_mask(h) ((h)->alignment_mask) 219*53ee8cc1Swenshuai.xi 220*53ee8cc1Swenshuai.xi /* To prevent prototype warnings provide complete argument list. */ 221*53ee8cc1Swenshuai.xi #define obstack_init(h) \ 222*53ee8cc1Swenshuai.xi _obstack_begin ((h), 0, 0, \ 223*53ee8cc1Swenshuai.xi (void *(*) (long)) obstack_chunk_alloc, \ 224*53ee8cc1Swenshuai.xi (void (*) (void *)) obstack_chunk_free) 225*53ee8cc1Swenshuai.xi 226*53ee8cc1Swenshuai.xi #define obstack_begin(h, size) \ 227*53ee8cc1Swenshuai.xi _obstack_begin ((h), (size), 0, \ 228*53ee8cc1Swenshuai.xi (void *(*) (long)) obstack_chunk_alloc, \ 229*53ee8cc1Swenshuai.xi (void (*) (void *)) obstack_chunk_free) 230*53ee8cc1Swenshuai.xi 231*53ee8cc1Swenshuai.xi #define obstack_specify_allocation(h, size, alignment, chunkfun, freefun) \ 232*53ee8cc1Swenshuai.xi _obstack_begin ((h), (size), (alignment), \ 233*53ee8cc1Swenshuai.xi (void *(*) (long)) (chunkfun), \ 234*53ee8cc1Swenshuai.xi (void (*) (void *)) (freefun)) 235*53ee8cc1Swenshuai.xi 236*53ee8cc1Swenshuai.xi #define obstack_specify_allocation_with_arg(h, size, alignment, chunkfun, freefun, arg) \ 237*53ee8cc1Swenshuai.xi _obstack_begin_1 ((h), (size), (alignment), \ 238*53ee8cc1Swenshuai.xi (void *(*) (void *, long)) (chunkfun), \ 239*53ee8cc1Swenshuai.xi (void (*) (void *, void *)) (freefun), (arg)) 240*53ee8cc1Swenshuai.xi 241*53ee8cc1Swenshuai.xi #define obstack_chunkfun(h, newchunkfun) \ 242*53ee8cc1Swenshuai.xi ((h) -> chunkfun = (struct _obstack_chunk *(*)(void *, long)) (newchunkfun)) 243*53ee8cc1Swenshuai.xi 244*53ee8cc1Swenshuai.xi #define obstack_freefun(h, newfreefun) \ 245*53ee8cc1Swenshuai.xi ((h) -> freefun = (void (*)(void *, struct _obstack_chunk *)) (newfreefun)) 246*53ee8cc1Swenshuai.xi 247*53ee8cc1Swenshuai.xi #define obstack_1grow_fast(h,achar) (*((h)->next_free)++ = (achar)) 248*53ee8cc1Swenshuai.xi 249*53ee8cc1Swenshuai.xi #define obstack_blank_fast(h,n) ((h)->next_free += (n)) 250*53ee8cc1Swenshuai.xi 251*53ee8cc1Swenshuai.xi #define obstack_memory_used(h) _obstack_memory_used (h) 252*53ee8cc1Swenshuai.xi 253*53ee8cc1Swenshuai.xi #if defined __GNUC__ && defined __STDC__ && __STDC__ 254*53ee8cc1Swenshuai.xi /* NextStep 2.0 cc is really gcc 1.93 but it defines __GNUC__ = 2 and 255*53ee8cc1Swenshuai.xi does not implement __extension__. But that compiler doesn't define 256*53ee8cc1Swenshuai.xi __GNUC_MINOR__. */ 257*53ee8cc1Swenshuai.xi # if __GNUC__ < 2 || (__NeXT__ && !__GNUC_MINOR__) 258*53ee8cc1Swenshuai.xi # define __extension__ 259*53ee8cc1Swenshuai.xi # endif 260*53ee8cc1Swenshuai.xi 261*53ee8cc1Swenshuai.xi /* For GNU C, if not -traditional, 262*53ee8cc1Swenshuai.xi we can define these macros to compute all args only once 263*53ee8cc1Swenshuai.xi without using a global variable. 264*53ee8cc1Swenshuai.xi Also, we can avoid using the `temp' slot, to make faster code. */ 265*53ee8cc1Swenshuai.xi 266*53ee8cc1Swenshuai.xi # define obstack_object_size(OBSTACK) \ 267*53ee8cc1Swenshuai.xi __extension__ \ 268*53ee8cc1Swenshuai.xi ({ struct obstack const *__o = (OBSTACK); \ 269*53ee8cc1Swenshuai.xi (unsigned) (__o->next_free - __o->object_base); }) 270*53ee8cc1Swenshuai.xi 271*53ee8cc1Swenshuai.xi # define obstack_room(OBSTACK) \ 272*53ee8cc1Swenshuai.xi __extension__ \ 273*53ee8cc1Swenshuai.xi ({ struct obstack const *__o = (OBSTACK); \ 274*53ee8cc1Swenshuai.xi (unsigned) (__o->chunk_limit - __o->next_free); }) 275*53ee8cc1Swenshuai.xi 276*53ee8cc1Swenshuai.xi # define obstack_make_room(OBSTACK,length) \ 277*53ee8cc1Swenshuai.xi __extension__ \ 278*53ee8cc1Swenshuai.xi ({ struct obstack *__o = (OBSTACK); \ 279*53ee8cc1Swenshuai.xi int __len = (length); \ 280*53ee8cc1Swenshuai.xi if (__o->chunk_limit - __o->next_free < __len) \ 281*53ee8cc1Swenshuai.xi _obstack_newchunk (__o, __len); \ 282*53ee8cc1Swenshuai.xi (void) 0; }) 283*53ee8cc1Swenshuai.xi 284*53ee8cc1Swenshuai.xi # define obstack_empty_p(OBSTACK) \ 285*53ee8cc1Swenshuai.xi __extension__ \ 286*53ee8cc1Swenshuai.xi ({ struct obstack const *__o = (OBSTACK); \ 287*53ee8cc1Swenshuai.xi (__o->chunk->prev == 0 \ 288*53ee8cc1Swenshuai.xi && __o->next_free == __PTR_ALIGN ((char *) __o->chunk, \ 289*53ee8cc1Swenshuai.xi __o->chunk->contents, \ 290*53ee8cc1Swenshuai.xi __o->alignment_mask)); }) 291*53ee8cc1Swenshuai.xi 292*53ee8cc1Swenshuai.xi # define obstack_grow(OBSTACK,where,length) \ 293*53ee8cc1Swenshuai.xi __extension__ \ 294*53ee8cc1Swenshuai.xi ({ struct obstack *__o = (OBSTACK); \ 295*53ee8cc1Swenshuai.xi int __len = (length); \ 296*53ee8cc1Swenshuai.xi if (__o->next_free + __len > __o->chunk_limit) \ 297*53ee8cc1Swenshuai.xi _obstack_newchunk (__o, __len); \ 298*53ee8cc1Swenshuai.xi memcpy (__o->next_free, where, __len); \ 299*53ee8cc1Swenshuai.xi __o->next_free += __len; \ 300*53ee8cc1Swenshuai.xi (void) 0; }) 301*53ee8cc1Swenshuai.xi 302*53ee8cc1Swenshuai.xi # define obstack_grow0(OBSTACK,where,length) \ 303*53ee8cc1Swenshuai.xi __extension__ \ 304*53ee8cc1Swenshuai.xi ({ struct obstack *__o = (OBSTACK); \ 305*53ee8cc1Swenshuai.xi int __len = (length); \ 306*53ee8cc1Swenshuai.xi if (__o->next_free + __len + 1 > __o->chunk_limit) \ 307*53ee8cc1Swenshuai.xi _obstack_newchunk (__o, __len + 1); \ 308*53ee8cc1Swenshuai.xi memcpy (__o->next_free, where, __len); \ 309*53ee8cc1Swenshuai.xi __o->next_free += __len; \ 310*53ee8cc1Swenshuai.xi *(__o->next_free)++ = 0; \ 311*53ee8cc1Swenshuai.xi (void) 0; }) 312*53ee8cc1Swenshuai.xi 313*53ee8cc1Swenshuai.xi # define obstack_1grow(OBSTACK,datum) \ 314*53ee8cc1Swenshuai.xi __extension__ \ 315*53ee8cc1Swenshuai.xi ({ struct obstack *__o = (OBSTACK); \ 316*53ee8cc1Swenshuai.xi if (__o->next_free + 1 > __o->chunk_limit) \ 317*53ee8cc1Swenshuai.xi _obstack_newchunk (__o, 1); \ 318*53ee8cc1Swenshuai.xi obstack_1grow_fast (__o, datum); \ 319*53ee8cc1Swenshuai.xi (void) 0; }) 320*53ee8cc1Swenshuai.xi 321*53ee8cc1Swenshuai.xi /* These assume that the obstack alignment is good enough for pointers 322*53ee8cc1Swenshuai.xi or ints, and that the data added so far to the current object 323*53ee8cc1Swenshuai.xi shares that much alignment. */ 324*53ee8cc1Swenshuai.xi 325*53ee8cc1Swenshuai.xi # define obstack_ptr_grow(OBSTACK,datum) \ 326*53ee8cc1Swenshuai.xi __extension__ \ 327*53ee8cc1Swenshuai.xi ({ struct obstack *__o = (OBSTACK); \ 328*53ee8cc1Swenshuai.xi if (__o->next_free + sizeof (void *) > __o->chunk_limit) \ 329*53ee8cc1Swenshuai.xi _obstack_newchunk (__o, sizeof (void *)); \ 330*53ee8cc1Swenshuai.xi obstack_ptr_grow_fast (__o, datum); }) \ 331*53ee8cc1Swenshuai.xi 332*53ee8cc1Swenshuai.xi # define obstack_int_grow(OBSTACK,datum) \ 333*53ee8cc1Swenshuai.xi __extension__ \ 334*53ee8cc1Swenshuai.xi ({ struct obstack *__o = (OBSTACK); \ 335*53ee8cc1Swenshuai.xi if (__o->next_free + sizeof (int) > __o->chunk_limit) \ 336*53ee8cc1Swenshuai.xi _obstack_newchunk (__o, sizeof (int)); \ 337*53ee8cc1Swenshuai.xi obstack_int_grow_fast (__o, datum); }) 338*53ee8cc1Swenshuai.xi 339*53ee8cc1Swenshuai.xi # define obstack_ptr_grow_fast(OBSTACK,aptr) \ 340*53ee8cc1Swenshuai.xi __extension__ \ 341*53ee8cc1Swenshuai.xi ({ struct obstack *__o1 = (OBSTACK); \ 342*53ee8cc1Swenshuai.xi *(const void **) __o1->next_free = (aptr); \ 343*53ee8cc1Swenshuai.xi __o1->next_free += sizeof (const void *); \ 344*53ee8cc1Swenshuai.xi (void) 0; }) 345*53ee8cc1Swenshuai.xi 346*53ee8cc1Swenshuai.xi # define obstack_int_grow_fast(OBSTACK,aint) \ 347*53ee8cc1Swenshuai.xi __extension__ \ 348*53ee8cc1Swenshuai.xi ({ struct obstack *__o1 = (OBSTACK); \ 349*53ee8cc1Swenshuai.xi *(int *) __o1->next_free = (aint); \ 350*53ee8cc1Swenshuai.xi __o1->next_free += sizeof (int); \ 351*53ee8cc1Swenshuai.xi (void) 0; }) 352*53ee8cc1Swenshuai.xi 353*53ee8cc1Swenshuai.xi # define obstack_blank(OBSTACK,length) \ 354*53ee8cc1Swenshuai.xi __extension__ \ 355*53ee8cc1Swenshuai.xi ({ struct obstack *__o = (OBSTACK); \ 356*53ee8cc1Swenshuai.xi int __len = (length); \ 357*53ee8cc1Swenshuai.xi if (__o->chunk_limit - __o->next_free < __len) \ 358*53ee8cc1Swenshuai.xi _obstack_newchunk (__o, __len); \ 359*53ee8cc1Swenshuai.xi obstack_blank_fast (__o, __len); \ 360*53ee8cc1Swenshuai.xi (void) 0; }) 361*53ee8cc1Swenshuai.xi 362*53ee8cc1Swenshuai.xi # define obstack_alloc(OBSTACK,length) \ 363*53ee8cc1Swenshuai.xi __extension__ \ 364*53ee8cc1Swenshuai.xi ({ struct obstack *__h = (OBSTACK); \ 365*53ee8cc1Swenshuai.xi obstack_blank (__h, (length)); \ 366*53ee8cc1Swenshuai.xi obstack_finish (__h); }) 367*53ee8cc1Swenshuai.xi 368*53ee8cc1Swenshuai.xi # define obstack_copy(OBSTACK,where,length) \ 369*53ee8cc1Swenshuai.xi __extension__ \ 370*53ee8cc1Swenshuai.xi ({ struct obstack *__h = (OBSTACK); \ 371*53ee8cc1Swenshuai.xi obstack_grow (__h, (where), (length)); \ 372*53ee8cc1Swenshuai.xi obstack_finish (__h); }) 373*53ee8cc1Swenshuai.xi 374*53ee8cc1Swenshuai.xi # define obstack_copy0(OBSTACK,where,length) \ 375*53ee8cc1Swenshuai.xi __extension__ \ 376*53ee8cc1Swenshuai.xi ({ struct obstack *__h = (OBSTACK); \ 377*53ee8cc1Swenshuai.xi obstack_grow0 (__h, (where), (length)); \ 378*53ee8cc1Swenshuai.xi obstack_finish (__h); }) 379*53ee8cc1Swenshuai.xi 380*53ee8cc1Swenshuai.xi /* The local variable is named __o1 to avoid a name conflict 381*53ee8cc1Swenshuai.xi when obstack_blank is called. */ 382*53ee8cc1Swenshuai.xi # define obstack_finish(OBSTACK) \ 383*53ee8cc1Swenshuai.xi __extension__ \ 384*53ee8cc1Swenshuai.xi ({ struct obstack *__o1 = (OBSTACK); \ 385*53ee8cc1Swenshuai.xi void *__value = (void *) __o1->object_base; \ 386*53ee8cc1Swenshuai.xi if (__o1->next_free == __value) \ 387*53ee8cc1Swenshuai.xi __o1->maybe_empty_object = 1; \ 388*53ee8cc1Swenshuai.xi __o1->next_free \ 389*53ee8cc1Swenshuai.xi = __PTR_ALIGN (__o1->object_base, __o1->next_free, \ 390*53ee8cc1Swenshuai.xi __o1->alignment_mask); \ 391*53ee8cc1Swenshuai.xi if (__o1->next_free - (char *)__o1->chunk \ 392*53ee8cc1Swenshuai.xi > __o1->chunk_limit - (char *)__o1->chunk) \ 393*53ee8cc1Swenshuai.xi __o1->next_free = __o1->chunk_limit; \ 394*53ee8cc1Swenshuai.xi __o1->object_base = __o1->next_free; \ 395*53ee8cc1Swenshuai.xi __value; }) 396*53ee8cc1Swenshuai.xi 397*53ee8cc1Swenshuai.xi # define obstack_free(OBSTACK, OBJ) \ 398*53ee8cc1Swenshuai.xi __extension__ \ 399*53ee8cc1Swenshuai.xi ({ struct obstack *__o = (OBSTACK); \ 400*53ee8cc1Swenshuai.xi void *__obj = (OBJ); \ 401*53ee8cc1Swenshuai.xi if (__obj > (void *)__o->chunk && __obj < (void *)__o->chunk_limit) \ 402*53ee8cc1Swenshuai.xi __o->next_free = __o->object_base = (char *)__obj; \ 403*53ee8cc1Swenshuai.xi else (obstack_free) (__o, __obj); }) 404*53ee8cc1Swenshuai.xi 405*53ee8cc1Swenshuai.xi #else /* not __GNUC__ or not __STDC__ */ 406*53ee8cc1Swenshuai.xi 407*53ee8cc1Swenshuai.xi # define obstack_object_size(h) \ 408*53ee8cc1Swenshuai.xi (unsigned) ((h)->next_free - (h)->object_base) 409*53ee8cc1Swenshuai.xi 410*53ee8cc1Swenshuai.xi # define obstack_room(h) \ 411*53ee8cc1Swenshuai.xi (unsigned) ((h)->chunk_limit - (h)->next_free) 412*53ee8cc1Swenshuai.xi 413*53ee8cc1Swenshuai.xi # define obstack_empty_p(h) \ 414*53ee8cc1Swenshuai.xi ((h)->chunk->prev == 0 \ 415*53ee8cc1Swenshuai.xi && (h)->next_free == __PTR_ALIGN ((char *) (h)->chunk, \ 416*53ee8cc1Swenshuai.xi (h)->chunk->contents, \ 417*53ee8cc1Swenshuai.xi (h)->alignment_mask)) 418*53ee8cc1Swenshuai.xi 419*53ee8cc1Swenshuai.xi /* Note that the call to _obstack_newchunk is enclosed in (..., 0) 420*53ee8cc1Swenshuai.xi so that we can avoid having void expressions 421*53ee8cc1Swenshuai.xi in the arms of the conditional expression. 422*53ee8cc1Swenshuai.xi Casting the third operand to void was tried before, 423*53ee8cc1Swenshuai.xi but some compilers won't accept it. */ 424*53ee8cc1Swenshuai.xi 425*53ee8cc1Swenshuai.xi # define obstack_make_room(h,length) \ 426*53ee8cc1Swenshuai.xi ( (h)->temp.tempint = (length), \ 427*53ee8cc1Swenshuai.xi (((h)->next_free + (h)->temp.tempint > (h)->chunk_limit) \ 428*53ee8cc1Swenshuai.xi ? (_obstack_newchunk ((h), (h)->temp.tempint), 0) : 0)) 429*53ee8cc1Swenshuai.xi 430*53ee8cc1Swenshuai.xi # define obstack_grow(h,where,length) \ 431*53ee8cc1Swenshuai.xi ( (h)->temp.tempint = (length), \ 432*53ee8cc1Swenshuai.xi (((h)->next_free + (h)->temp.tempint > (h)->chunk_limit) \ 433*53ee8cc1Swenshuai.xi ? (_obstack_newchunk ((h), (h)->temp.tempint), 0) : 0), \ 434*53ee8cc1Swenshuai.xi memcpy ((h)->next_free, where, (h)->temp.tempint), \ 435*53ee8cc1Swenshuai.xi (h)->next_free += (h)->temp.tempint) 436*53ee8cc1Swenshuai.xi 437*53ee8cc1Swenshuai.xi # define obstack_grow0(h,where,length) \ 438*53ee8cc1Swenshuai.xi ( (h)->temp.tempint = (length), \ 439*53ee8cc1Swenshuai.xi (((h)->next_free + (h)->temp.tempint + 1 > (h)->chunk_limit) \ 440*53ee8cc1Swenshuai.xi ? (_obstack_newchunk ((h), (h)->temp.tempint + 1), 0) : 0), \ 441*53ee8cc1Swenshuai.xi memcpy ((h)->next_free, where, (h)->temp.tempint), \ 442*53ee8cc1Swenshuai.xi (h)->next_free += (h)->temp.tempint, \ 443*53ee8cc1Swenshuai.xi *((h)->next_free)++ = 0) 444*53ee8cc1Swenshuai.xi 445*53ee8cc1Swenshuai.xi # define obstack_1grow(h,datum) \ 446*53ee8cc1Swenshuai.xi ( (((h)->next_free + 1 > (h)->chunk_limit) \ 447*53ee8cc1Swenshuai.xi ? (_obstack_newchunk ((h), 1), 0) : 0), \ 448*53ee8cc1Swenshuai.xi obstack_1grow_fast (h, datum)) 449*53ee8cc1Swenshuai.xi 450*53ee8cc1Swenshuai.xi # define obstack_ptr_grow(h,datum) \ 451*53ee8cc1Swenshuai.xi ( (((h)->next_free + sizeof (char *) > (h)->chunk_limit) \ 452*53ee8cc1Swenshuai.xi ? (_obstack_newchunk ((h), sizeof (char *)), 0) : 0), \ 453*53ee8cc1Swenshuai.xi obstack_ptr_grow_fast (h, datum)) 454*53ee8cc1Swenshuai.xi 455*53ee8cc1Swenshuai.xi # define obstack_int_grow(h,datum) \ 456*53ee8cc1Swenshuai.xi ( (((h)->next_free + sizeof (int) > (h)->chunk_limit) \ 457*53ee8cc1Swenshuai.xi ? (_obstack_newchunk ((h), sizeof (int)), 0) : 0), \ 458*53ee8cc1Swenshuai.xi obstack_int_grow_fast (h, datum)) 459*53ee8cc1Swenshuai.xi 460*53ee8cc1Swenshuai.xi # define obstack_ptr_grow_fast(h,aptr) \ 461*53ee8cc1Swenshuai.xi (((const void **) ((h)->next_free += sizeof (void *)))[-1] = (aptr)) 462*53ee8cc1Swenshuai.xi 463*53ee8cc1Swenshuai.xi # define obstack_int_grow_fast(h,aint) \ 464*53ee8cc1Swenshuai.xi (((int *) ((h)->next_free += sizeof (int)))[-1] = (aint)) 465*53ee8cc1Swenshuai.xi 466*53ee8cc1Swenshuai.xi # define obstack_blank(h,length) \ 467*53ee8cc1Swenshuai.xi ( (h)->temp.tempint = (length), \ 468*53ee8cc1Swenshuai.xi (((h)->chunk_limit - (h)->next_free < (h)->temp.tempint) \ 469*53ee8cc1Swenshuai.xi ? (_obstack_newchunk ((h), (h)->temp.tempint), 0) : 0), \ 470*53ee8cc1Swenshuai.xi obstack_blank_fast (h, (h)->temp.tempint)) 471*53ee8cc1Swenshuai.xi 472*53ee8cc1Swenshuai.xi # define obstack_alloc(h,length) \ 473*53ee8cc1Swenshuai.xi (obstack_blank ((h), (length)), obstack_finish ((h))) 474*53ee8cc1Swenshuai.xi 475*53ee8cc1Swenshuai.xi # define obstack_copy(h,where,length) \ 476*53ee8cc1Swenshuai.xi (obstack_grow ((h), (where), (length)), obstack_finish ((h))) 477*53ee8cc1Swenshuai.xi 478*53ee8cc1Swenshuai.xi # define obstack_copy0(h,where,length) \ 479*53ee8cc1Swenshuai.xi (obstack_grow0 ((h), (where), (length)), obstack_finish ((h))) 480*53ee8cc1Swenshuai.xi 481*53ee8cc1Swenshuai.xi # define obstack_finish(h) \ 482*53ee8cc1Swenshuai.xi ( ((h)->next_free == (h)->object_base \ 483*53ee8cc1Swenshuai.xi ? (((h)->maybe_empty_object = 1), 0) \ 484*53ee8cc1Swenshuai.xi : 0), \ 485*53ee8cc1Swenshuai.xi (h)->temp.tempptr = (h)->object_base, \ 486*53ee8cc1Swenshuai.xi (h)->next_free \ 487*53ee8cc1Swenshuai.xi = __PTR_ALIGN ((h)->object_base, (h)->next_free, \ 488*53ee8cc1Swenshuai.xi (h)->alignment_mask), \ 489*53ee8cc1Swenshuai.xi (((h)->next_free - (char *) (h)->chunk \ 490*53ee8cc1Swenshuai.xi > (h)->chunk_limit - (char *) (h)->chunk) \ 491*53ee8cc1Swenshuai.xi ? ((h)->next_free = (h)->chunk_limit) : 0), \ 492*53ee8cc1Swenshuai.xi (h)->object_base = (h)->next_free, \ 493*53ee8cc1Swenshuai.xi (h)->temp.tempptr) 494*53ee8cc1Swenshuai.xi 495*53ee8cc1Swenshuai.xi # define obstack_free(h,obj) \ 496*53ee8cc1Swenshuai.xi ( (h)->temp.tempint = (char *) (obj) - (char *) (h)->chunk, \ 497*53ee8cc1Swenshuai.xi ((((h)->temp.tempint > 0 \ 498*53ee8cc1Swenshuai.xi && (h)->temp.tempint < (h)->chunk_limit - (char *) (h)->chunk)) \ 499*53ee8cc1Swenshuai.xi ? (int) ((h)->next_free = (h)->object_base \ 500*53ee8cc1Swenshuai.xi = (h)->temp.tempint + (char *) (h)->chunk) \ 501*53ee8cc1Swenshuai.xi : (((obstack_free) ((h), (h)->temp.tempint + (char *) (h)->chunk), 0), 0))) 502*53ee8cc1Swenshuai.xi 503*53ee8cc1Swenshuai.xi #endif /* not __GNUC__ or not __STDC__ */ 504*53ee8cc1Swenshuai.xi 505*53ee8cc1Swenshuai.xi #ifdef __cplusplus 506*53ee8cc1Swenshuai.xi } /* C++ */ 507*53ee8cc1Swenshuai.xi #endif 508*53ee8cc1Swenshuai.xi 509*53ee8cc1Swenshuai.xi #endif /* obstack.h */ 510