12159047fSniklas /* obstack.h - object stack macros 2b55d4692Sfgsch Copyright 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1996, 1997, 1998, 3b55d4692Sfgsch 1999, 2000 4b55d4692Sfgsch Free Software Foundation, Inc. 5b305b0f1Sespie 6b305b0f1Sespie 7b305b0f1Sespie NOTE: The canonical source of this file is maintained with the GNU C Library. 8b305b0f1Sespie Bugs can be reported to bug-glibc@gnu.org. 92159047fSniklas 102159047fSniklas This program is free software; you can redistribute it and/or modify it 11b305b0f1Sespie under the terms of the GNU General Public License as published by the 122159047fSniklas Free Software Foundation; either version 2, or (at your option) any 132159047fSniklas later version. 142159047fSniklas 152159047fSniklas This program is distributed in the hope that it will be useful, 162159047fSniklas but WITHOUT ANY WARRANTY; without even the implied warranty of 172159047fSniklas MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18b305b0f1Sespie GNU General Public License for more details. 192159047fSniklas 20b305b0f1Sespie You should have received a copy of the GNU General Public License 212159047fSniklas along with this program; if not, write to the Free Software 22b305b0f1Sespie Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, 23b305b0f1Sespie USA. */ 242159047fSniklas 252159047fSniklas /* Summary: 262159047fSniklas 272159047fSniklas All the apparent functions defined here are macros. The idea 282159047fSniklas is that you would use these pre-tested macros to solve a 292159047fSniklas very specific set of problems, and they would run fast. 302159047fSniklas Caution: no side-effects in arguments please!! They may be 312159047fSniklas evaluated MANY times!! 322159047fSniklas 332159047fSniklas These macros operate a stack of objects. Each object starts life 342159047fSniklas small, and may grow to maturity. (Consider building a word syllable 352159047fSniklas by syllable.) An object can move while it is growing. Once it has 362159047fSniklas been "finished" it never changes address again. So the "top of the 372159047fSniklas stack" is typically an immature growing object, while the rest of the 382159047fSniklas stack is of mature, fixed size and fixed address objects. 392159047fSniklas 402159047fSniklas These routines grab large chunks of memory, using a function you 412159047fSniklas supply, called `obstack_chunk_alloc'. On occasion, they free chunks, 422159047fSniklas by calling `obstack_chunk_free'. You must define them and declare 432159047fSniklas them before using any obstack macros. 442159047fSniklas 452159047fSniklas Each independent stack is represented by a `struct obstack'. 462159047fSniklas Each of the obstack macros expects a pointer to such a structure 472159047fSniklas as the first argument. 482159047fSniklas 492159047fSniklas One motivation for this package is the problem of growing char strings 502159047fSniklas in symbol tables. Unless you are "fascist pig with a read-only mind" 512159047fSniklas --Gosper's immortal quote from HAKMEM item 154, out of context--you 522159047fSniklas would not like to put any arbitrary upper limit on the length of your 532159047fSniklas symbols. 542159047fSniklas 552159047fSniklas In practice this often means you will build many short symbols and a 562159047fSniklas few long symbols. At the time you are reading a symbol you don't know 572159047fSniklas how long it is. One traditional method is to read a symbol into a 582159047fSniklas buffer, realloc()ating the buffer every time you try to read a symbol 592159047fSniklas that is longer than the buffer. This is beaut, but you still will 602159047fSniklas want to copy the symbol from the buffer to a more permanent 612159047fSniklas symbol-table entry say about half the time. 622159047fSniklas 632159047fSniklas With obstacks, you can work differently. Use one obstack for all symbol 642159047fSniklas names. As you read a symbol, grow the name in the obstack gradually. 652159047fSniklas When the name is complete, finalize it. Then, if the symbol exists already, 662159047fSniklas free the newly read name. 672159047fSniklas 682159047fSniklas The way we do this is to take a large chunk, allocating memory from 692159047fSniklas low addresses. When you want to build a symbol in the chunk you just 702159047fSniklas add chars above the current "high water mark" in the chunk. When you 712159047fSniklas have finished adding chars, because you got to the end of the symbol, 722159047fSniklas you know how long the chars are, and you can create a new object. 732159047fSniklas Mostly the chars will not burst over the highest address of the chunk, 742159047fSniklas because you would typically expect a chunk to be (say) 100 times as 752159047fSniklas long as an average object. 762159047fSniklas 772159047fSniklas In case that isn't clear, when we have enough chars to make up 782159047fSniklas the object, THEY ARE ALREADY CONTIGUOUS IN THE CHUNK (guaranteed) 792159047fSniklas so we just point to it where it lies. No moving of chars is 802159047fSniklas needed and this is the second win: potentially long strings need 812159047fSniklas never be explicitly shuffled. Once an object is formed, it does not 822159047fSniklas change its address during its lifetime. 832159047fSniklas 842159047fSniklas When the chars burst over a chunk boundary, we allocate a larger 852159047fSniklas chunk, and then copy the partly formed object from the end of the old 862159047fSniklas chunk to the beginning of the new larger chunk. We then carry on 872159047fSniklas accreting characters to the end of the object as we normally would. 882159047fSniklas 892159047fSniklas A special macro is provided to add a single char at a time to a 902159047fSniklas growing object. This allows the use of register variables, which 912159047fSniklas break the ordinary 'growth' macro. 922159047fSniklas 932159047fSniklas Summary: 942159047fSniklas We allocate large chunks. 952159047fSniklas We carve out one object at a time from the current chunk. 962159047fSniklas Once carved, an object never moves. 972159047fSniklas We are free to append data of any size to the currently 982159047fSniklas growing object. 992159047fSniklas Exactly one object is growing in an obstack at any one time. 1002159047fSniklas You can run one obstack per control block. 1012159047fSniklas You may have as many control blocks as you dare. 1022159047fSniklas Because of the way we do it, you can `unwind' an obstack 1032159047fSniklas back to a previous state. (You may remove objects much 1042159047fSniklas as you would with a stack.) 1052159047fSniklas */ 1062159047fSniklas 1072159047fSniklas 1082159047fSniklas /* Don't do the contents of this file more than once. */ 1092159047fSniklas 110b305b0f1Sespie #ifndef _OBSTACK_H 111b305b0f1Sespie #define _OBSTACK_H 1 112b305b0f1Sespie 113b305b0f1Sespie #ifdef __cplusplus 114b305b0f1Sespie extern "C" { 115b305b0f1Sespie #endif 1162159047fSniklas 1172159047fSniklas /* We use subtraction of (char *) 0 instead of casting to int 1182159047fSniklas because on word-addressable machines a simple cast to int 1192159047fSniklas may ignore the byte-within-word field of the pointer. */ 1202159047fSniklas 1212159047fSniklas #ifndef __PTR_TO_INT 1222159047fSniklas # define __PTR_TO_INT(P) ((P) - (char *) 0) 1232159047fSniklas #endif 1242159047fSniklas 1252159047fSniklas #ifndef __INT_TO_PTR 1262159047fSniklas # define __INT_TO_PTR(P) ((P) + (char *) 0) 1272159047fSniklas #endif 1282159047fSniklas 129b305b0f1Sespie /* We need the type of the resulting object. If __PTRDIFF_TYPE__ is 130b305b0f1Sespie defined, as with GNU C, use that; that way we don't pollute the 131b305b0f1Sespie namespace with <stddef.h>'s symbols. Otherwise, if <stddef.h> is 132b305b0f1Sespie available, include it and use ptrdiff_t. In traditional C, long is 133b305b0f1Sespie the best that we can do. */ 1342159047fSniklas 135b305b0f1Sespie #ifdef __PTRDIFF_TYPE__ 136b305b0f1Sespie # define PTR_INT_TYPE __PTRDIFF_TYPE__ 137b305b0f1Sespie #else 138b305b0f1Sespie # ifdef HAVE_STDDEF_H 1392159047fSniklas # include <stddef.h> 1402159047fSniklas # define PTR_INT_TYPE ptrdiff_t 1412159047fSniklas # else 1422159047fSniklas # define PTR_INT_TYPE long 1432159047fSniklas # endif 144b305b0f1Sespie #endif 145b305b0f1Sespie 146b305b0f1Sespie #if defined _LIBC || defined HAVE_STRING_H 147b305b0f1Sespie # include <string.h> 148b305b0f1Sespie # if defined __STDC__ && __STDC__ 149b305b0f1Sespie # define _obstack_memcpy(To, From, N) memcpy ((To), (From), (N)) 150b305b0f1Sespie # else 151b305b0f1Sespie # define _obstack_memcpy(To, From, N) memcpy ((To), (char *)(From), (N)) 152b305b0f1Sespie # endif 153b305b0f1Sespie #else 154b305b0f1Sespie # ifdef memcpy 155b305b0f1Sespie # define _obstack_memcpy(To, From, N) memcpy ((To), (char *)(From), (N)) 156b305b0f1Sespie # else 157b305b0f1Sespie # define _obstack_memcpy(To, From, N) bcopy ((char *)(From), (To), (N)) 158b305b0f1Sespie # endif 159b305b0f1Sespie #endif 1602159047fSniklas 1612159047fSniklas struct _obstack_chunk /* Lives at front of each chunk. */ 1622159047fSniklas { 1632159047fSniklas char *limit; /* 1 past end of this chunk */ 1642159047fSniklas struct _obstack_chunk *prev; /* address of prior chunk or NULL */ 1652159047fSniklas char contents[4]; /* objects begin here */ 1662159047fSniklas }; 1672159047fSniklas 1682159047fSniklas struct obstack /* control current object in current chunk */ 1692159047fSniklas { 1702159047fSniklas long chunk_size; /* preferred size to allocate chunks in */ 1712159047fSniklas struct _obstack_chunk *chunk; /* address of current struct obstack_chunk */ 1722159047fSniklas char *object_base; /* address of object we are building */ 1732159047fSniklas char *next_free; /* where to add next char to current object */ 1742159047fSniklas char *chunk_limit; /* address of char after current chunk */ 1752159047fSniklas PTR_INT_TYPE temp; /* Temporary for some macros. */ 1762159047fSniklas int alignment_mask; /* Mask of alignment for each object. */ 177b305b0f1Sespie #if defined __STDC__ && __STDC__ 178b305b0f1Sespie /* These prototypes vary based on `use_extra_arg', and we use 179b305b0f1Sespie casts to the prototypeless function type in all assignments, 180b305b0f1Sespie but having prototypes here quiets -Wstrict-prototypes. */ 181b305b0f1Sespie struct _obstack_chunk *(*chunkfun) (void *, long); 182b305b0f1Sespie void (*freefun) (void *, struct _obstack_chunk *); 183b305b0f1Sespie void *extra_arg; /* first arg for chunk alloc/dealloc funcs */ 184b305b0f1Sespie #else 1852159047fSniklas struct _obstack_chunk *(*chunkfun) (); /* User's fcn to allocate a chunk. */ 1862159047fSniklas void (*freefun) (); /* User's function to free a chunk. */ 1872159047fSniklas char *extra_arg; /* first arg for chunk alloc/dealloc funcs */ 188b305b0f1Sespie #endif 1892159047fSniklas unsigned use_extra_arg:1; /* chunk alloc/dealloc funcs take extra arg */ 1902159047fSniklas unsigned maybe_empty_object:1;/* There is a possibility that the current 1912159047fSniklas chunk contains a zero-length object. This 1922159047fSniklas prevents freeing the chunk if we allocate 1932159047fSniklas a bigger chunk to replace it. */ 194b305b0f1Sespie unsigned alloc_failed:1; /* No longer used, as we now call the failed 195b305b0f1Sespie handler on error, but retained for binary 196b305b0f1Sespie compatibility. */ 1972159047fSniklas }; 1982159047fSniklas 1992159047fSniklas /* Declare the external functions we use; they are in obstack.c. */ 2002159047fSniklas 201b305b0f1Sespie #if defined __STDC__ && __STDC__ 2022159047fSniklas extern void _obstack_newchunk (struct obstack *, int); 2032159047fSniklas extern void _obstack_free (struct obstack *, void *); 2042159047fSniklas extern int _obstack_begin (struct obstack *, int, int, 205b305b0f1Sespie void *(*) (long), void (*) (void *)); 2062159047fSniklas extern int _obstack_begin_1 (struct obstack *, int, int, 207b305b0f1Sespie void *(*) (void *, long), 208b305b0f1Sespie void (*) (void *, void *), void *); 209c88b1d6cSniklas extern int _obstack_memory_used (struct obstack *); 2102159047fSniklas #else 2112159047fSniklas extern void _obstack_newchunk (); 2122159047fSniklas extern void _obstack_free (); 2132159047fSniklas extern int _obstack_begin (); 2142159047fSniklas extern int _obstack_begin_1 (); 215c88b1d6cSniklas extern int _obstack_memory_used (); 2162159047fSniklas #endif 2172159047fSniklas 218b305b0f1Sespie #if defined __STDC__ && __STDC__ 2192159047fSniklas 2202159047fSniklas /* Do the function-declarations after the structs 2212159047fSniklas but before defining the macros. */ 2222159047fSniklas 2232159047fSniklas void obstack_init (struct obstack *obstack); 2242159047fSniklas 2252159047fSniklas void * obstack_alloc (struct obstack *obstack, int size); 2262159047fSniklas 2272159047fSniklas void * obstack_copy (struct obstack *obstack, void *address, int size); 2282159047fSniklas void * obstack_copy0 (struct obstack *obstack, void *address, int size); 2292159047fSniklas 2302159047fSniklas void obstack_free (struct obstack *obstack, void *block); 2312159047fSniklas 2322159047fSniklas void obstack_blank (struct obstack *obstack, int size); 2332159047fSniklas 2342159047fSniklas void obstack_grow (struct obstack *obstack, void *data, int size); 2352159047fSniklas void obstack_grow0 (struct obstack *obstack, void *data, int size); 2362159047fSniklas 2372159047fSniklas void obstack_1grow (struct obstack *obstack, int data_char); 2382159047fSniklas void obstack_ptr_grow (struct obstack *obstack, void *data); 2392159047fSniklas void obstack_int_grow (struct obstack *obstack, int data); 2402159047fSniklas 2412159047fSniklas void * obstack_finish (struct obstack *obstack); 2422159047fSniklas 2432159047fSniklas int obstack_object_size (struct obstack *obstack); 2442159047fSniklas 2452159047fSniklas int obstack_room (struct obstack *obstack); 246b305b0f1Sespie void obstack_make_room (struct obstack *obstack, int size); 2472159047fSniklas void obstack_1grow_fast (struct obstack *obstack, int data_char); 2482159047fSniklas void obstack_ptr_grow_fast (struct obstack *obstack, void *data); 2492159047fSniklas void obstack_int_grow_fast (struct obstack *obstack, int data); 2502159047fSniklas void obstack_blank_fast (struct obstack *obstack, int size); 2512159047fSniklas 2522159047fSniklas void * obstack_base (struct obstack *obstack); 2532159047fSniklas void * obstack_next_free (struct obstack *obstack); 2542159047fSniklas int obstack_alignment_mask (struct obstack *obstack); 2552159047fSniklas int obstack_chunk_size (struct obstack *obstack); 256c88b1d6cSniklas int obstack_memory_used (struct obstack *obstack); 2572159047fSniklas 2582159047fSniklas #endif /* __STDC__ */ 2592159047fSniklas 2602159047fSniklas /* Non-ANSI C cannot really support alternative functions for these macros, 2612159047fSniklas so we do not declare them. */ 262b305b0f1Sespie 263b305b0f1Sespie /* Error handler called when `obstack_chunk_alloc' failed to allocate 264b305b0f1Sespie more memory. This can be set to a user defined function. The 265b305b0f1Sespie default action is to print a message and abort. */ 266b305b0f1Sespie #if defined __STDC__ && __STDC__ 267b305b0f1Sespie extern void (*obstack_alloc_failed_handler) (void); 268b305b0f1Sespie #else 269b305b0f1Sespie extern void (*obstack_alloc_failed_handler) (); 270b305b0f1Sespie #endif 271b305b0f1Sespie 272b305b0f1Sespie /* Exit value used when `print_and_abort' is used. */ 273b305b0f1Sespie extern int obstack_exit_failure; 2742159047fSniklas 2752159047fSniklas /* Pointer to beginning of object being allocated or to be allocated next. 2762159047fSniklas Note that this might not be the final address of the object 2772159047fSniklas because a new chunk might be needed to hold the final size. */ 2782159047fSniklas 279b305b0f1Sespie #define obstack_base(h) ((h)->object_base) 2802159047fSniklas 2812159047fSniklas /* Size for allocating ordinary chunks. */ 2822159047fSniklas 2832159047fSniklas #define obstack_chunk_size(h) ((h)->chunk_size) 2842159047fSniklas 2852159047fSniklas /* Pointer to next byte not yet allocated in current chunk. */ 2862159047fSniklas 287b305b0f1Sespie #define obstack_next_free(h) ((h)->next_free) 2882159047fSniklas 2892159047fSniklas /* Mask specifying low bits that should be clear in address of an object. */ 2902159047fSniklas 2912159047fSniklas #define obstack_alignment_mask(h) ((h)->alignment_mask) 2922159047fSniklas 293b305b0f1Sespie /* To prevent prototype warnings provide complete argument list in 294b305b0f1Sespie standard C version. */ 295b305b0f1Sespie #if defined __STDC__ && __STDC__ 296b305b0f1Sespie 297b305b0f1Sespie # define obstack_init(h) \ 298b305b0f1Sespie _obstack_begin ((h), 0, 0, \ 299b305b0f1Sespie (void *(*) (long)) obstack_chunk_alloc, (void (*) (void *)) obstack_chunk_free) 300b305b0f1Sespie 301b305b0f1Sespie # define obstack_begin(h, size) \ 302b305b0f1Sespie _obstack_begin ((h), (size), 0, \ 303b305b0f1Sespie (void *(*) (long)) obstack_chunk_alloc, (void (*) (void *)) obstack_chunk_free) 304b305b0f1Sespie 305b305b0f1Sespie # define obstack_specify_allocation(h, size, alignment, chunkfun, freefun) \ 306b305b0f1Sespie _obstack_begin ((h), (size), (alignment), \ 307b305b0f1Sespie (void *(*) (long)) (chunkfun), (void (*) (void *)) (freefun)) 308b305b0f1Sespie 309b305b0f1Sespie # define obstack_specify_allocation_with_arg(h, size, alignment, chunkfun, freefun, arg) \ 310b305b0f1Sespie _obstack_begin_1 ((h), (size), (alignment), \ 311b305b0f1Sespie (void *(*) (void *, long)) (chunkfun), \ 312b305b0f1Sespie (void (*) (void *, void *)) (freefun), (arg)) 313b305b0f1Sespie 314b305b0f1Sespie # define obstack_chunkfun(h, newchunkfun) \ 315b305b0f1Sespie ((h) -> chunkfun = (struct _obstack_chunk *(*)(void *, long)) (newchunkfun)) 316b305b0f1Sespie 317b305b0f1Sespie # define obstack_freefun(h, newfreefun) \ 318b305b0f1Sespie ((h) -> freefun = (void (*)(void *, struct _obstack_chunk *)) (newfreefun)) 319b305b0f1Sespie 320b305b0f1Sespie #else 321b305b0f1Sespie 3222159047fSniklas # define obstack_init(h) \ 3232159047fSniklas _obstack_begin ((h), 0, 0, \ 3242159047fSniklas (void *(*) ()) obstack_chunk_alloc, (void (*) ()) obstack_chunk_free) 3252159047fSniklas 3262159047fSniklas # define obstack_begin(h, size) \ 3272159047fSniklas _obstack_begin ((h), (size), 0, \ 3282159047fSniklas (void *(*) ()) obstack_chunk_alloc, (void (*) ()) obstack_chunk_free) 3292159047fSniklas 3302159047fSniklas # define obstack_specify_allocation(h, size, alignment, chunkfun, freefun) \ 3312159047fSniklas _obstack_begin ((h), (size), (alignment), \ 3322159047fSniklas (void *(*) ()) (chunkfun), (void (*) ()) (freefun)) 3332159047fSniklas 3342159047fSniklas # define obstack_specify_allocation_with_arg(h, size, alignment, chunkfun, freefun, arg) \ 3352159047fSniklas _obstack_begin_1 ((h), (size), (alignment), \ 3362159047fSniklas (void *(*) ()) (chunkfun), (void (*) ()) (freefun), (arg)) 3372159047fSniklas 3382159047fSniklas # define obstack_chunkfun(h, newchunkfun) \ 3392159047fSniklas ((h) -> chunkfun = (struct _obstack_chunk *(*)()) (newchunkfun)) 3402159047fSniklas 3412159047fSniklas # define obstack_freefun(h, newfreefun) \ 3422159047fSniklas ((h) -> freefun = (void (*)()) (newfreefun)) 3432159047fSniklas 344b305b0f1Sespie #endif 345b305b0f1Sespie 346*007c2a45Smiod #define obstack_1grow_fast(h,achar) (*((h)->next_free)++ = (achar)) 3472159047fSniklas 3482159047fSniklas #define obstack_blank_fast(h,n) ((h)->next_free += (n)) 349c88b1d6cSniklas 350c88b1d6cSniklas #define obstack_memory_used(h) _obstack_memory_used (h) 3512159047fSniklas 352b305b0f1Sespie #if defined __GNUC__ && defined __STDC__ && __STDC__ 353b305b0f1Sespie /* NextStep 2.0 cc is really gcc 1.93 but it defines __GNUC__ = 2 and 354b305b0f1Sespie does not implement __extension__. But that compiler doesn't define 355b305b0f1Sespie __GNUC_MINOR__. */ 356b305b0f1Sespie # if __GNUC__ < 2 || (__NeXT__ && !__GNUC_MINOR__) 3572159047fSniklas # define __extension__ 3582159047fSniklas # endif 3592159047fSniklas 3602159047fSniklas /* For GNU C, if not -traditional, 3612159047fSniklas we can define these macros to compute all args only once 3622159047fSniklas without using a global variable. 3632159047fSniklas Also, we can avoid using the `temp' slot, to make faster code. */ 3642159047fSniklas 3652159047fSniklas # define obstack_object_size(OBSTACK) \ 3662159047fSniklas __extension__ \ 3672159047fSniklas ({ struct obstack *__o = (OBSTACK); \ 3682159047fSniklas (unsigned) (__o->next_free - __o->object_base); }) 3692159047fSniklas 3702159047fSniklas # define obstack_room(OBSTACK) \ 3712159047fSniklas __extension__ \ 3722159047fSniklas ({ struct obstack *__o = (OBSTACK); \ 3732159047fSniklas (unsigned) (__o->chunk_limit - __o->next_free); }) 3742159047fSniklas 375b305b0f1Sespie # define obstack_make_room(OBSTACK,length) \ 376b305b0f1Sespie __extension__ \ 377b305b0f1Sespie ({ struct obstack *__o = (OBSTACK); \ 378b305b0f1Sespie int __len = (length); \ 379b305b0f1Sespie if (__o->chunk_limit - __o->next_free < __len) \ 380b305b0f1Sespie _obstack_newchunk (__o, __len); \ 381b305b0f1Sespie (void) 0; }) 382b305b0f1Sespie 383b305b0f1Sespie # define obstack_empty_p(OBSTACK) \ 384b305b0f1Sespie __extension__ \ 385b305b0f1Sespie ({ struct obstack *__o = (OBSTACK); \ 386b305b0f1Sespie (__o->chunk->prev == 0 && __o->next_free - __o->chunk->contents == 0); }) 387b305b0f1Sespie 3882159047fSniklas # define obstack_grow(OBSTACK,where,length) \ 3892159047fSniklas __extension__ \ 3902159047fSniklas ({ struct obstack *__o = (OBSTACK); \ 3912159047fSniklas int __len = (length); \ 3922159047fSniklas if (__o->next_free + __len > __o->chunk_limit) \ 3932159047fSniklas _obstack_newchunk (__o, __len); \ 394b305b0f1Sespie _obstack_memcpy (__o->next_free, (where), __len); \ 3952159047fSniklas __o->next_free += __len; \ 3962159047fSniklas (void) 0; }) 3972159047fSniklas 3982159047fSniklas # define obstack_grow0(OBSTACK,where,length) \ 3992159047fSniklas __extension__ \ 4002159047fSniklas ({ struct obstack *__o = (OBSTACK); \ 4012159047fSniklas int __len = (length); \ 4022159047fSniklas if (__o->next_free + __len + 1 > __o->chunk_limit) \ 4032159047fSniklas _obstack_newchunk (__o, __len + 1); \ 404b305b0f1Sespie _obstack_memcpy (__o->next_free, (where), __len); \ 4052159047fSniklas __o->next_free += __len; \ 4062159047fSniklas *(__o->next_free)++ = 0; \ 4072159047fSniklas (void) 0; }) 4082159047fSniklas 4092159047fSniklas # define obstack_1grow(OBSTACK,datum) \ 4102159047fSniklas __extension__ \ 4112159047fSniklas ({ struct obstack *__o = (OBSTACK); \ 4122159047fSniklas if (__o->next_free + 1 > __o->chunk_limit) \ 4132159047fSniklas _obstack_newchunk (__o, 1); \ 414*007c2a45Smiod obstack_1grow_fast (__o, datum); \ 4152159047fSniklas (void) 0; }) 4162159047fSniklas 4172159047fSniklas /* These assume that the obstack alignment is good enough for pointers or ints, 4182159047fSniklas and that the data added so far to the current object 4192159047fSniklas shares that much alignment. */ 4202159047fSniklas 4212159047fSniklas # define obstack_ptr_grow(OBSTACK,datum) \ 4222159047fSniklas __extension__ \ 4232159047fSniklas ({ struct obstack *__o = (OBSTACK); \ 4242159047fSniklas if (__o->next_free + sizeof (void *) > __o->chunk_limit) \ 4252159047fSniklas _obstack_newchunk (__o, sizeof (void *)); \ 426*007c2a45Smiod obstack_ptr_grow_fast (__o, datum); }) 4272159047fSniklas 4282159047fSniklas # define obstack_int_grow(OBSTACK,datum) \ 4292159047fSniklas __extension__ \ 4302159047fSniklas ({ struct obstack *__o = (OBSTACK); \ 4312159047fSniklas if (__o->next_free + sizeof (int) > __o->chunk_limit) \ 4322159047fSniklas _obstack_newchunk (__o, sizeof (int)); \ 433*007c2a45Smiod obstack_int_grow_fast (__o, datum); }) 434*007c2a45Smiod 435*007c2a45Smiod # define obstack_ptr_grow_fast(OBSTACK,aptr) \ 436*007c2a45Smiod __extension__ \ 437*007c2a45Smiod ({ struct obstack *__o1 = (OBSTACK); \ 438*007c2a45Smiod *(const void **) __o1->next_free = (aptr); \ 439*007c2a45Smiod __o1->next_free += sizeof (const void *); \ 4402159047fSniklas (void) 0; }) 4412159047fSniklas 442*007c2a45Smiod # define obstack_int_grow_fast(OBSTACK,aint) \ 443*007c2a45Smiod __extension__ \ 444*007c2a45Smiod ({ struct obstack *__o1 = (OBSTACK); \ 445*007c2a45Smiod *(int *) __o1->next_free = (aint); \ 446*007c2a45Smiod __o1->next_free += sizeof (int); \ 447*007c2a45Smiod (void) 0; }) 4482159047fSniklas 4492159047fSniklas # define obstack_blank(OBSTACK,length) \ 4502159047fSniklas __extension__ \ 4512159047fSniklas ({ struct obstack *__o = (OBSTACK); \ 4522159047fSniklas int __len = (length); \ 4532159047fSniklas if (__o->chunk_limit - __o->next_free < __len) \ 4542159047fSniklas _obstack_newchunk (__o, __len); \ 455*007c2a45Smiod obstack_blank_fast (__o, __len); \ 4562159047fSniklas (void) 0; }) 4572159047fSniklas 4582159047fSniklas # define obstack_alloc(OBSTACK,length) \ 4592159047fSniklas __extension__ \ 4602159047fSniklas ({ struct obstack *__h = (OBSTACK); \ 4612159047fSniklas obstack_blank (__h, (length)); \ 4622159047fSniklas obstack_finish (__h); }) 4632159047fSniklas 4642159047fSniklas # define obstack_copy(OBSTACK,where,length) \ 4652159047fSniklas __extension__ \ 4662159047fSniklas ({ struct obstack *__h = (OBSTACK); \ 4672159047fSniklas obstack_grow (__h, (where), (length)); \ 4682159047fSniklas obstack_finish (__h); }) 4692159047fSniklas 4702159047fSniklas # define obstack_copy0(OBSTACK,where,length) \ 4712159047fSniklas __extension__ \ 4722159047fSniklas ({ struct obstack *__h = (OBSTACK); \ 4732159047fSniklas obstack_grow0 (__h, (where), (length)); \ 4742159047fSniklas obstack_finish (__h); }) 4752159047fSniklas 4762159047fSniklas /* The local variable is named __o1 to avoid a name conflict 4772159047fSniklas when obstack_blank is called. */ 4782159047fSniklas # define obstack_finish(OBSTACK) \ 4792159047fSniklas __extension__ \ 4802159047fSniklas ({ struct obstack *__o1 = (OBSTACK); \ 4812159047fSniklas void *value; \ 4822159047fSniklas value = (void *) __o1->object_base; \ 4832159047fSniklas if (__o1->next_free == value) \ 4842159047fSniklas __o1->maybe_empty_object = 1; \ 4852159047fSniklas __o1->next_free \ 4862159047fSniklas = __INT_TO_PTR ((__PTR_TO_INT (__o1->next_free)+__o1->alignment_mask)\ 4872159047fSniklas & ~ (__o1->alignment_mask)); \ 4882159047fSniklas if (__o1->next_free - (char *)__o1->chunk \ 4892159047fSniklas > __o1->chunk_limit - (char *)__o1->chunk) \ 4902159047fSniklas __o1->next_free = __o1->chunk_limit; \ 4912159047fSniklas __o1->object_base = __o1->next_free; \ 4922159047fSniklas value; }) 4932159047fSniklas 4942159047fSniklas # define obstack_free(OBSTACK, OBJ) \ 4952159047fSniklas __extension__ \ 4962159047fSniklas ({ struct obstack *__o = (OBSTACK); \ 4972159047fSniklas void *__obj = (OBJ); \ 4982159047fSniklas if (__obj > (void *)__o->chunk && __obj < (void *)__o->chunk_limit) \ 4992159047fSniklas __o->next_free = __o->object_base = __obj; \ 5002159047fSniklas else (obstack_free) (__o, __obj); }) 5012159047fSniklas 5022159047fSniklas #else /* not __GNUC__ or not __STDC__ */ 5032159047fSniklas 5042159047fSniklas # define obstack_object_size(h) \ 505b305b0f1Sespie (unsigned) ((h)->next_free - (h)->object_base) 5062159047fSniklas 5072159047fSniklas # define obstack_room(h) \ 5082159047fSniklas (unsigned) ((h)->chunk_limit - (h)->next_free) 5092159047fSniklas 510b305b0f1Sespie # define obstack_empty_p(h) \ 511b305b0f1Sespie ((h)->chunk->prev == 0 && (h)->next_free - (h)->chunk->contents == 0) 512b305b0f1Sespie 5132159047fSniklas /* Note that the call to _obstack_newchunk is enclosed in (..., 0) 5142159047fSniklas so that we can avoid having void expressions 5152159047fSniklas in the arms of the conditional expression. 5162159047fSniklas Casting the third operand to void was tried before, 5172159047fSniklas but some compilers won't accept it. */ 5182159047fSniklas 519b305b0f1Sespie # define obstack_make_room(h,length) \ 520b305b0f1Sespie ( (h)->temp = (length), \ 521b305b0f1Sespie (((h)->next_free + (h)->temp > (h)->chunk_limit) \ 522b305b0f1Sespie ? (_obstack_newchunk ((h), (h)->temp), 0) : 0)) 523b305b0f1Sespie 5242159047fSniklas # define obstack_grow(h,where,length) \ 5252159047fSniklas ( (h)->temp = (length), \ 5262159047fSniklas (((h)->next_free + (h)->temp > (h)->chunk_limit) \ 5272159047fSniklas ? (_obstack_newchunk ((h), (h)->temp), 0) : 0), \ 528b305b0f1Sespie _obstack_memcpy ((h)->next_free, (where), (h)->temp), \ 529b305b0f1Sespie (h)->next_free += (h)->temp) 5302159047fSniklas 5312159047fSniklas # define obstack_grow0(h,where,length) \ 5322159047fSniklas ( (h)->temp = (length), \ 5332159047fSniklas (((h)->next_free + (h)->temp + 1 > (h)->chunk_limit) \ 5342159047fSniklas ? (_obstack_newchunk ((h), (h)->temp + 1), 0) : 0), \ 535b305b0f1Sespie _obstack_memcpy ((h)->next_free, (where), (h)->temp), \ 5362159047fSniklas (h)->next_free += (h)->temp, \ 537b305b0f1Sespie *((h)->next_free)++ = 0) 5382159047fSniklas 5392159047fSniklas # define obstack_1grow(h,datum) \ 5402159047fSniklas ( (((h)->next_free + 1 > (h)->chunk_limit) \ 5412159047fSniklas ? (_obstack_newchunk ((h), 1), 0) : 0), \ 542*007c2a45Smiod obstack_1grow_fast (h, datum)) 5432159047fSniklas 5442159047fSniklas # define obstack_ptr_grow(h,datum) \ 5452159047fSniklas ( (((h)->next_free + sizeof (char *) > (h)->chunk_limit) \ 5462159047fSniklas ? (_obstack_newchunk ((h), sizeof (char *)), 0) : 0), \ 547*007c2a45Smiod obstack_ptr_grow_fast (h, datum)) 5482159047fSniklas 5492159047fSniklas # define obstack_int_grow(h,datum) \ 5502159047fSniklas ( (((h)->next_free + sizeof (int) > (h)->chunk_limit) \ 5512159047fSniklas ? (_obstack_newchunk ((h), sizeof (int)), 0) : 0), \ 552*007c2a45Smiod obstack_int_grow_fast (h, datum)) 5532159047fSniklas 554*007c2a45Smiod # define obstack_ptr_grow_fast(h,aptr) \ 555*007c2a45Smiod (((const void **) ((h)->next_free += sizeof (void *)))[-1] = (aptr)) 556*007c2a45Smiod 557*007c2a45Smiod # define obstack_int_grow_fast(h,aint) \ 558*007c2a45Smiod (((int *) ((h)->next_free += sizeof (int)))[-1] = (aptr)) 5592159047fSniklas 5602159047fSniklas # define obstack_blank(h,length) \ 5612159047fSniklas ( (h)->temp = (length), \ 5622159047fSniklas (((h)->chunk_limit - (h)->next_free < (h)->temp) \ 5632159047fSniklas ? (_obstack_newchunk ((h), (h)->temp), 0) : 0), \ 564*007c2a45Smiod obstack_blank_fast (h, (h)->temp)) 5652159047fSniklas 5662159047fSniklas # define obstack_alloc(h,length) \ 5672159047fSniklas (obstack_blank ((h), (length)), obstack_finish ((h))) 5682159047fSniklas 5692159047fSniklas # define obstack_copy(h,where,length) \ 5702159047fSniklas (obstack_grow ((h), (where), (length)), obstack_finish ((h))) 5712159047fSniklas 5722159047fSniklas # define obstack_copy0(h,where,length) \ 5732159047fSniklas (obstack_grow0 ((h), (where), (length)), obstack_finish ((h))) 5742159047fSniklas 5752159047fSniklas # define obstack_finish(h) \ 5762159047fSniklas ( ((h)->next_free == (h)->object_base \ 5772159047fSniklas ? (((h)->maybe_empty_object = 1), 0) \ 5782159047fSniklas : 0), \ 5792159047fSniklas (h)->temp = __PTR_TO_INT ((h)->object_base), \ 5802159047fSniklas (h)->next_free \ 5812159047fSniklas = __INT_TO_PTR ((__PTR_TO_INT ((h)->next_free)+(h)->alignment_mask) \ 5822159047fSniklas & ~ ((h)->alignment_mask)), \ 5832159047fSniklas (((h)->next_free - (char *) (h)->chunk \ 5842159047fSniklas > (h)->chunk_limit - (char *) (h)->chunk) \ 5852159047fSniklas ? ((h)->next_free = (h)->chunk_limit) : 0), \ 5862159047fSniklas (h)->object_base = (h)->next_free, \ 587b305b0f1Sespie __INT_TO_PTR ((h)->temp)) 5882159047fSniklas 589b305b0f1Sespie # if defined __STDC__ && __STDC__ 5902159047fSniklas # define obstack_free(h,obj) \ 5912159047fSniklas ( (h)->temp = (char *) (obj) - (char *) (h)->chunk, \ 5922159047fSniklas (((h)->temp > 0 && (h)->temp < (h)->chunk_limit - (char *) (h)->chunk)\ 5932159047fSniklas ? (int) ((h)->next_free = (h)->object_base \ 5942159047fSniklas = (h)->temp + (char *) (h)->chunk) \ 5952159047fSniklas : (((obstack_free) ((h), (h)->temp + (char *) (h)->chunk), 0), 0))) 5962159047fSniklas # else 5972159047fSniklas # define obstack_free(h,obj) \ 5982159047fSniklas ( (h)->temp = (char *) (obj) - (char *) (h)->chunk, \ 5992159047fSniklas (((h)->temp > 0 && (h)->temp < (h)->chunk_limit - (char *) (h)->chunk)\ 6002159047fSniklas ? (int) ((h)->next_free = (h)->object_base \ 6012159047fSniklas = (h)->temp + (char *) (h)->chunk) \ 6022159047fSniklas : (_obstack_free ((h), (h)->temp + (char *) (h)->chunk), 0))) 6032159047fSniklas # endif 6042159047fSniklas 6052159047fSniklas #endif /* not __GNUC__ or not __STDC__ */ 6062159047fSniklas 607b305b0f1Sespie #ifdef __cplusplus 608b305b0f1Sespie } /* C++ */ 609b305b0f1Sespie #endif 610b305b0f1Sespie 611b305b0f1Sespie #endif /* obstack.h */ 612