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