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