1130812Smarcel/* obstack.h - object stack macros 2130812Smarcel Copyright 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1996, 1997, 1998, 3130812Smarcel 1999, 2000 4130812Smarcel Free Software Foundation, Inc. 5130812Smarcel 6130812Smarcel 7130812Smarcel NOTE: The canonical source of this file is maintained with the GNU C Library. 8130812Smarcel Bugs can be reported to bug-glibc@gnu.org. 9130812Smarcel 10130812Smarcel This program is free software; you can redistribute it and/or modify it 11130812Smarcel under the terms of the GNU General Public License as published by the 12130812Smarcel Free Software Foundation; either version 2, or (at your option) any 13130812Smarcel later version. 14130812Smarcel 15130812Smarcel This program is distributed in the hope that it will be useful, 16130812Smarcel but WITHOUT ANY WARRANTY; without even the implied warranty of 17130812Smarcel MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18130812Smarcel GNU General Public License for more details. 19130812Smarcel 20130812Smarcel You should have received a copy of the GNU General Public License 21130812Smarcel along with this program; if not, write to the Free Software 22130812Smarcel Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, 23130812Smarcel USA. */ 24130812Smarcel 25130812Smarcel/* Summary: 26130812Smarcel 27130812SmarcelAll the apparent functions defined here are macros. The idea 28130812Smarcelis that you would use these pre-tested macros to solve a 29130812Smarcelvery specific set of problems, and they would run fast. 30130812SmarcelCaution: no side-effects in arguments please!! They may be 31130812Smarcelevaluated MANY times!! 32130812Smarcel 33130812SmarcelThese macros operate a stack of objects. Each object starts life 34130812Smarcelsmall, and may grow to maturity. (Consider building a word syllable 35130812Smarcelby syllable.) An object can move while it is growing. Once it has 36130812Smarcelbeen "finished" it never changes address again. So the "top of the 37130812Smarcelstack" is typically an immature growing object, while the rest of the 38130812Smarcelstack is of mature, fixed size and fixed address objects. 39130812Smarcel 40130812SmarcelThese routines grab large chunks of memory, using a function you 41130812Smarcelsupply, called `obstack_chunk_alloc'. On occasion, they free chunks, 42130812Smarcelby calling `obstack_chunk_free'. You must define them and declare 43130812Smarcelthem before using any obstack macros. 44130812Smarcel 45130812SmarcelEach independent stack is represented by a `struct obstack'. 46130812SmarcelEach of the obstack macros expects a pointer to such a structure 47130812Smarcelas the first argument. 48130812Smarcel 49130812SmarcelOne motivation for this package is the problem of growing char strings 50130812Smarcelin symbol tables. Unless you are "fascist pig with a read-only mind" 51130812Smarcel--Gosper's immortal quote from HAKMEM item 154, out of context--you 52130812Smarcelwould not like to put any arbitrary upper limit on the length of your 53130812Smarcelsymbols. 54130812Smarcel 55130812SmarcelIn practice this often means you will build many short symbols and a 56130812Smarcelfew long symbols. At the time you are reading a symbol you don't know 57130812Smarcelhow long it is. One traditional method is to read a symbol into a 58130812Smarcelbuffer, realloc()ating the buffer every time you try to read a symbol 59130812Smarcelthat is longer than the buffer. This is beaut, but you still will 60130812Smarcelwant to copy the symbol from the buffer to a more permanent 61130812Smarcelsymbol-table entry say about half the time. 62130812Smarcel 63130812SmarcelWith obstacks, you can work differently. Use one obstack for all symbol 64130812Smarcelnames. As you read a symbol, grow the name in the obstack gradually. 65130812SmarcelWhen the name is complete, finalize it. Then, if the symbol exists already, 66130812Smarcelfree the newly read name. 67130812Smarcel 68130812SmarcelThe way we do this is to take a large chunk, allocating memory from 69130812Smarcellow addresses. When you want to build a symbol in the chunk you just 70130812Smarceladd chars above the current "high water mark" in the chunk. When you 71130812Smarcelhave finished adding chars, because you got to the end of the symbol, 72130812Smarcelyou know how long the chars are, and you can create a new object. 73130812SmarcelMostly the chars will not burst over the highest address of the chunk, 74130812Smarcelbecause you would typically expect a chunk to be (say) 100 times as 75130812Smarcellong as an average object. 76130812Smarcel 77130812SmarcelIn case that isn't clear, when we have enough chars to make up 78130812Smarcelthe object, THEY ARE ALREADY CONTIGUOUS IN THE CHUNK (guaranteed) 79130812Smarcelso we just point to it where it lies. No moving of chars is 80130812Smarcelneeded and this is the second win: potentially long strings need 81130812Smarcelnever be explicitly shuffled. Once an object is formed, it does not 82130812Smarcelchange its address during its lifetime. 83130812Smarcel 84130812SmarcelWhen the chars burst over a chunk boundary, we allocate a larger 85130812Smarcelchunk, and then copy the partly formed object from the end of the old 86130812Smarcelchunk to the beginning of the new larger chunk. We then carry on 87130812Smarcelaccreting characters to the end of the object as we normally would. 88130812Smarcel 89130812SmarcelA special macro is provided to add a single char at a time to a 90130812Smarcelgrowing object. This allows the use of register variables, which 91130812Smarcelbreak the ordinary 'growth' macro. 92130812Smarcel 93130812SmarcelSummary: 94130812Smarcel We allocate large chunks. 95130812Smarcel We carve out one object at a time from the current chunk. 96130812Smarcel Once carved, an object never moves. 97130812Smarcel We are free to append data of any size to the currently 98130812Smarcel growing object. 99130812Smarcel Exactly one object is growing in an obstack at any one time. 100130812Smarcel You can run one obstack per control block. 101130812Smarcel You may have as many control blocks as you dare. 102130812Smarcel Because of the way we do it, you can `unwind' an obstack 103130812Smarcel back to a previous state. (You may remove objects much 104130812Smarcel as you would with a stack.) 105130812Smarcel*/ 106130812Smarcel 107130812Smarcel 108130812Smarcel/* Don't do the contents of this file more than once. */ 109130812Smarcel 110130812Smarcel#ifndef _OBSTACK_H 111130812Smarcel#define _OBSTACK_H 1 112130812Smarcel 113130812Smarcel#ifdef __cplusplus 114130812Smarcelextern "C" { 115130812Smarcel#endif 116130812Smarcel 117130812Smarcel/* We use subtraction of (char *) 0 instead of casting to int 118130812Smarcel because on word-addressable machines a simple cast to int 119130812Smarcel may ignore the byte-within-word field of the pointer. */ 120130812Smarcel 121130812Smarcel#ifndef __PTR_TO_INT 122130812Smarcel# define __PTR_TO_INT(P) ((P) - (char *) 0) 123130812Smarcel#endif 124130812Smarcel 125130812Smarcel#ifndef __INT_TO_PTR 126130812Smarcel# define __INT_TO_PTR(P) ((P) + (char *) 0) 127130812Smarcel#endif 128130812Smarcel 129130812Smarcel/* We need the type of the resulting object. If __PTRDIFF_TYPE__ is 130130812Smarcel defined, as with GNU C, use that; that way we don't pollute the 131130812Smarcel namespace with <stddef.h>'s symbols. Otherwise, if <stddef.h> is 132130812Smarcel available, include it and use ptrdiff_t. In traditional C, long is 133130812Smarcel the best that we can do. */ 134130812Smarcel 135130812Smarcel#ifdef __PTRDIFF_TYPE__ 136130812Smarcel# define PTR_INT_TYPE __PTRDIFF_TYPE__ 137130812Smarcel#else 138130812Smarcel# ifdef HAVE_STDDEF_H 139130812Smarcel# include <stddef.h> 140130812Smarcel# define PTR_INT_TYPE ptrdiff_t 141130812Smarcel# else 142130812Smarcel# define PTR_INT_TYPE long 143130812Smarcel# endif 144130812Smarcel#endif 145130812Smarcel 146130812Smarcel#if defined _LIBC || defined HAVE_STRING_H 147130812Smarcel# include <string.h> 148130812Smarcel# if defined __STDC__ && __STDC__ 149130812Smarcel# define _obstack_memcpy(To, From, N) memcpy ((To), (From), (N)) 150130812Smarcel# else 151130812Smarcel# define _obstack_memcpy(To, From, N) memcpy ((To), (char *)(From), (N)) 152130812Smarcel# endif 153130812Smarcel#else 154130812Smarcel# ifdef memcpy 155130812Smarcel# define _obstack_memcpy(To, From, N) memcpy ((To), (char *)(From), (N)) 156130812Smarcel# else 157130812Smarcel# define _obstack_memcpy(To, From, N) bcopy ((char *)(From), (To), (N)) 158130812Smarcel# endif 159130812Smarcel#endif 160130812Smarcel 161130812Smarcelstruct _obstack_chunk /* Lives at front of each chunk. */ 162130812Smarcel{ 163130812Smarcel char *limit; /* 1 past end of this chunk */ 164130812Smarcel struct _obstack_chunk *prev; /* address of prior chunk or NULL */ 165130812Smarcel char contents[4]; /* objects begin here */ 166130812Smarcel}; 167130812Smarcel 168130812Smarcelstruct obstack /* control current object in current chunk */ 169130812Smarcel{ 170130812Smarcel long chunk_size; /* preferred size to allocate chunks in */ 171130812Smarcel struct _obstack_chunk *chunk; /* address of current struct obstack_chunk */ 172130812Smarcel char *object_base; /* address of object we are building */ 173130812Smarcel char *next_free; /* where to add next char to current object */ 174130812Smarcel char *chunk_limit; /* address of char after current chunk */ 175130812Smarcel PTR_INT_TYPE temp; /* Temporary for some macros. */ 176130812Smarcel int alignment_mask; /* Mask of alignment for each object. */ 177130812Smarcel#if defined __STDC__ && __STDC__ 178130812Smarcel /* These prototypes vary based on `use_extra_arg', and we use 179130812Smarcel casts to the prototypeless function type in all assignments, 180130812Smarcel but having prototypes here quiets -Wstrict-prototypes. */ 181130812Smarcel struct _obstack_chunk *(*chunkfun) (void *, long); 182130812Smarcel void (*freefun) (void *, struct _obstack_chunk *); 183130812Smarcel void *extra_arg; /* first arg for chunk alloc/dealloc funcs */ 184130812Smarcel#else 185130812Smarcel struct _obstack_chunk *(*chunkfun) (); /* User's fcn to allocate a chunk. */ 186130812Smarcel void (*freefun) (); /* User's function to free a chunk. */ 187130812Smarcel char *extra_arg; /* first arg for chunk alloc/dealloc funcs */ 188130812Smarcel#endif 189130812Smarcel unsigned use_extra_arg:1; /* chunk alloc/dealloc funcs take extra arg */ 190130812Smarcel unsigned maybe_empty_object:1;/* There is a possibility that the current 191130812Smarcel chunk contains a zero-length object. This 192130812Smarcel prevents freeing the chunk if we allocate 193130812Smarcel a bigger chunk to replace it. */ 194130812Smarcel unsigned alloc_failed:1; /* No longer used, as we now call the failed 195130812Smarcel handler on error, but retained for binary 196130812Smarcel compatibility. */ 197130812Smarcel}; 198130812Smarcel 199130812Smarcel/* Declare the external functions we use; they are in obstack.c. */ 200130812Smarcel 201130812Smarcel#if defined __STDC__ && __STDC__ 202130812Smarcelextern void _obstack_newchunk (struct obstack *, int); 203130812Smarcelextern void _obstack_free (struct obstack *, void *); 204130812Smarcelextern int _obstack_begin (struct obstack *, int, int, 205130812Smarcel void *(*) (long), void (*) (void *)); 206130812Smarcelextern int _obstack_begin_1 (struct obstack *, int, int, 207130812Smarcel void *(*) (void *, long), 208130812Smarcel void (*) (void *, void *), void *); 209130812Smarcelextern int _obstack_memory_used (struct obstack *); 210130812Smarcel#else 211130812Smarcelextern void _obstack_newchunk (); 212130812Smarcelextern void _obstack_free (); 213130812Smarcelextern int _obstack_begin (); 214130812Smarcelextern int _obstack_begin_1 (); 215130812Smarcelextern int _obstack_memory_used (); 216130812Smarcel#endif 217130812Smarcel 218130812Smarcel#if defined __STDC__ && __STDC__ 219130812Smarcel 220130812Smarcel/* Do the function-declarations after the structs 221130812Smarcel but before defining the macros. */ 222130812Smarcel 223130812Smarcelvoid obstack_init (struct obstack *obstack); 224130812Smarcel 225130812Smarcelvoid * obstack_alloc (struct obstack *obstack, int size); 226130812Smarcel 227130812Smarcelvoid * obstack_copy (struct obstack *obstack, void *address, int size); 228130812Smarcelvoid * obstack_copy0 (struct obstack *obstack, void *address, int size); 229130812Smarcel 230130812Smarcelvoid obstack_free (struct obstack *obstack, void *block); 231130812Smarcel 232130812Smarcelvoid obstack_blank (struct obstack *obstack, int size); 233130812Smarcel 234130812Smarcelvoid obstack_grow (struct obstack *obstack, void *data, int size); 235130812Smarcelvoid obstack_grow0 (struct obstack *obstack, void *data, int size); 236130812Smarcel 237130812Smarcelvoid obstack_1grow (struct obstack *obstack, int data_char); 238130812Smarcelvoid obstack_ptr_grow (struct obstack *obstack, void *data); 239130812Smarcelvoid obstack_int_grow (struct obstack *obstack, int data); 240130812Smarcel 241130812Smarcelvoid * obstack_finish (struct obstack *obstack); 242130812Smarcel 243130812Smarcelint obstack_object_size (struct obstack *obstack); 244130812Smarcel 245130812Smarcelint obstack_room (struct obstack *obstack); 246130812Smarcelvoid obstack_make_room (struct obstack *obstack, int size); 247130812Smarcelvoid obstack_1grow_fast (struct obstack *obstack, int data_char); 248130812Smarcelvoid obstack_ptr_grow_fast (struct obstack *obstack, void *data); 249130812Smarcelvoid obstack_int_grow_fast (struct obstack *obstack, int data); 250130812Smarcelvoid obstack_blank_fast (struct obstack *obstack, int size); 251130812Smarcel 252130812Smarcelvoid * obstack_base (struct obstack *obstack); 253130812Smarcelvoid * obstack_next_free (struct obstack *obstack); 254130812Smarcelint obstack_alignment_mask (struct obstack *obstack); 255130812Smarcelint obstack_chunk_size (struct obstack *obstack); 256130812Smarcelint obstack_memory_used (struct obstack *obstack); 257130812Smarcel 258130812Smarcel#endif /* __STDC__ */ 259130812Smarcel 260130812Smarcel/* Non-ANSI C cannot really support alternative functions for these macros, 261130812Smarcel so we do not declare them. */ 262130812Smarcel 263130812Smarcel/* Error handler called when `obstack_chunk_alloc' failed to allocate 264130812Smarcel more memory. This can be set to a user defined function. The 265130812Smarcel default action is to print a message and abort. */ 266130812Smarcel#if defined __STDC__ && __STDC__ 267130812Smarcelextern void (*obstack_alloc_failed_handler) (void); 268130812Smarcel#else 269130812Smarcelextern void (*obstack_alloc_failed_handler) (); 270130812Smarcel#endif 271130812Smarcel 272130812Smarcel/* Exit value used when `print_and_abort' is used. */ 273130812Smarcelextern int obstack_exit_failure; 274130812Smarcel 275130812Smarcel/* Pointer to beginning of object being allocated or to be allocated next. 276130812Smarcel Note that this might not be the final address of the object 277130812Smarcel because a new chunk might be needed to hold the final size. */ 278130812Smarcel 279130812Smarcel#define obstack_base(h) ((h)->object_base) 280130812Smarcel 281130812Smarcel/* Size for allocating ordinary chunks. */ 282130812Smarcel 283130812Smarcel#define obstack_chunk_size(h) ((h)->chunk_size) 284130812Smarcel 285130812Smarcel/* Pointer to next byte not yet allocated in current chunk. */ 286130812Smarcel 287130812Smarcel#define obstack_next_free(h) ((h)->next_free) 288130812Smarcel 289130812Smarcel/* Mask specifying low bits that should be clear in address of an object. */ 290130812Smarcel 291130812Smarcel#define obstack_alignment_mask(h) ((h)->alignment_mask) 292130812Smarcel 293130812Smarcel/* To prevent prototype warnings provide complete argument list in 294130812Smarcel standard C version. */ 295130812Smarcel#if defined __STDC__ && __STDC__ 296130812Smarcel 297130812Smarcel# define obstack_init(h) \ 298130812Smarcel _obstack_begin ((h), 0, 0, \ 299130812Smarcel (void *(*) (long)) obstack_chunk_alloc, (void (*) (void *)) obstack_chunk_free) 300130812Smarcel 301130812Smarcel# define obstack_begin(h, size) \ 302130812Smarcel _obstack_begin ((h), (size), 0, \ 303130812Smarcel (void *(*) (long)) obstack_chunk_alloc, (void (*) (void *)) obstack_chunk_free) 304130812Smarcel 305130812Smarcel# define obstack_specify_allocation(h, size, alignment, chunkfun, freefun) \ 306130812Smarcel _obstack_begin ((h), (size), (alignment), \ 307130812Smarcel (void *(*) (long)) (chunkfun), (void (*) (void *)) (freefun)) 308130812Smarcel 309130812Smarcel# define obstack_specify_allocation_with_arg(h, size, alignment, chunkfun, freefun, arg) \ 310130812Smarcel _obstack_begin_1 ((h), (size), (alignment), \ 311130812Smarcel (void *(*) (void *, long)) (chunkfun), \ 312130812Smarcel (void (*) (void *, void *)) (freefun), (arg)) 313130812Smarcel 314130812Smarcel# define obstack_chunkfun(h, newchunkfun) \ 315130812Smarcel ((h) -> chunkfun = (struct _obstack_chunk *(*)(void *, long)) (newchunkfun)) 316130812Smarcel 317130812Smarcel# define obstack_freefun(h, newfreefun) \ 318130812Smarcel ((h) -> freefun = (void (*)(void *, struct _obstack_chunk *)) (newfreefun)) 319130812Smarcel 320130812Smarcel#else 321130812Smarcel 322130812Smarcel# define obstack_init(h) \ 323130812Smarcel _obstack_begin ((h), 0, 0, \ 324130812Smarcel (void *(*) ()) obstack_chunk_alloc, (void (*) ()) obstack_chunk_free) 325130812Smarcel 326130812Smarcel# define obstack_begin(h, size) \ 327130812Smarcel _obstack_begin ((h), (size), 0, \ 328130812Smarcel (void *(*) ()) obstack_chunk_alloc, (void (*) ()) obstack_chunk_free) 329130812Smarcel 330130812Smarcel# define obstack_specify_allocation(h, size, alignment, chunkfun, freefun) \ 331130812Smarcel _obstack_begin ((h), (size), (alignment), \ 332130812Smarcel (void *(*) ()) (chunkfun), (void (*) ()) (freefun)) 333130812Smarcel 334130812Smarcel# define obstack_specify_allocation_with_arg(h, size, alignment, chunkfun, freefun, arg) \ 335130812Smarcel _obstack_begin_1 ((h), (size), (alignment), \ 336130812Smarcel (void *(*) ()) (chunkfun), (void (*) ()) (freefun), (arg)) 337130812Smarcel 338130812Smarcel# define obstack_chunkfun(h, newchunkfun) \ 339130812Smarcel ((h) -> chunkfun = (struct _obstack_chunk *(*)()) (newchunkfun)) 340130812Smarcel 341130812Smarcel# define obstack_freefun(h, newfreefun) \ 342130812Smarcel ((h) -> freefun = (void (*)()) (newfreefun)) 343130812Smarcel 344130812Smarcel#endif 345130812Smarcel 346130812Smarcel#define obstack_1grow_fast(h,achar) (*((h)->next_free)++ = (achar)) 347130812Smarcel 348130812Smarcel#define obstack_blank_fast(h,n) ((h)->next_free += (n)) 349130812Smarcel 350130812Smarcel#define obstack_memory_used(h) _obstack_memory_used (h) 351130812Smarcel 352130812Smarcel#if defined __GNUC__ && defined __STDC__ && __STDC__ 353130812Smarcel/* NextStep 2.0 cc is really gcc 1.93 but it defines __GNUC__ = 2 and 354130812Smarcel does not implement __extension__. But that compiler doesn't define 355130812Smarcel __GNUC_MINOR__. */ 356130812Smarcel# if __GNUC__ < 2 || (__NeXT__ && !__GNUC_MINOR__) 357130812Smarcel# define __extension__ 358130812Smarcel# endif 359130812Smarcel 360130812Smarcel/* For GNU C, if not -traditional, 361130812Smarcel we can define these macros to compute all args only once 362130812Smarcel without using a global variable. 363130812Smarcel Also, we can avoid using the `temp' slot, to make faster code. */ 364130812Smarcel 365130812Smarcel# define obstack_object_size(OBSTACK) \ 366130812Smarcel __extension__ \ 367130812Smarcel ({ struct obstack *__o = (OBSTACK); \ 368130812Smarcel (unsigned) (__o->next_free - __o->object_base); }) 369130812Smarcel 370130812Smarcel# define obstack_room(OBSTACK) \ 371130812Smarcel __extension__ \ 372130812Smarcel ({ struct obstack *__o = (OBSTACK); \ 373130812Smarcel (unsigned) (__o->chunk_limit - __o->next_free); }) 374130812Smarcel 375130812Smarcel# define obstack_make_room(OBSTACK,length) \ 376130812Smarcel__extension__ \ 377130812Smarcel({ struct obstack *__o = (OBSTACK); \ 378130812Smarcel int __len = (length); \ 379130812Smarcel if (__o->chunk_limit - __o->next_free < __len) \ 380130812Smarcel _obstack_newchunk (__o, __len); \ 381130812Smarcel (void) 0; }) 382130812Smarcel 383130812Smarcel# define obstack_empty_p(OBSTACK) \ 384130812Smarcel __extension__ \ 385130812Smarcel ({ struct obstack *__o = (OBSTACK); \ 386130812Smarcel (__o->chunk->prev == 0 && __o->next_free - __o->chunk->contents == 0); }) 387130812Smarcel 388130812Smarcel# define obstack_grow(OBSTACK,where,length) \ 389130812Smarcel__extension__ \ 390130812Smarcel({ struct obstack *__o = (OBSTACK); \ 391130812Smarcel int __len = (length); \ 392130812Smarcel if (__o->next_free + __len > __o->chunk_limit) \ 393130812Smarcel _obstack_newchunk (__o, __len); \ 394130812Smarcel _obstack_memcpy (__o->next_free, (where), __len); \ 395130812Smarcel __o->next_free += __len; \ 396130812Smarcel (void) 0; }) 397130812Smarcel 398130812Smarcel# define obstack_grow0(OBSTACK,where,length) \ 399130812Smarcel__extension__ \ 400130812Smarcel({ struct obstack *__o = (OBSTACK); \ 401130812Smarcel int __len = (length); \ 402130812Smarcel if (__o->next_free + __len + 1 > __o->chunk_limit) \ 403130812Smarcel _obstack_newchunk (__o, __len + 1); \ 404130812Smarcel _obstack_memcpy (__o->next_free, (where), __len); \ 405130812Smarcel __o->next_free += __len; \ 406130812Smarcel *(__o->next_free)++ = 0; \ 407130812Smarcel (void) 0; }) 408130812Smarcel 409130812Smarcel# define obstack_1grow(OBSTACK,datum) \ 410130812Smarcel__extension__ \ 411130812Smarcel({ struct obstack *__o = (OBSTACK); \ 412130812Smarcel if (__o->next_free + 1 > __o->chunk_limit) \ 413130812Smarcel _obstack_newchunk (__o, 1); \ 414130812Smarcel obstack_1grow_fast (__o, datum); \ 415130812Smarcel (void) 0; }) 416130812Smarcel 417130812Smarcel/* These assume that the obstack alignment is good enough for pointers or ints, 418130812Smarcel and that the data added so far to the current object 419130812Smarcel shares that much alignment. */ 420130812Smarcel 421130812Smarcel# define obstack_ptr_grow(OBSTACK,datum) \ 422130812Smarcel__extension__ \ 423130812Smarcel({ struct obstack *__o = (OBSTACK); \ 424130812Smarcel if (__o->next_free + sizeof (void *) > __o->chunk_limit) \ 425130812Smarcel _obstack_newchunk (__o, sizeof (void *)); \ 426130812Smarcel obstack_ptr_grow_fast (__o, datum); }) 427130812Smarcel 428130812Smarcel# define obstack_int_grow(OBSTACK,datum) \ 429130812Smarcel__extension__ \ 430130812Smarcel({ struct obstack *__o = (OBSTACK); \ 431130812Smarcel if (__o->next_free + sizeof (int) > __o->chunk_limit) \ 432130812Smarcel _obstack_newchunk (__o, sizeof (int)); \ 433130812Smarcel obstack_int_grow_fast (__o, datum); }) 434130812Smarcel 435130812Smarcel# define obstack_ptr_grow_fast(OBSTACK,aptr) \ 436130812Smarcel__extension__ \ 437130812Smarcel({ struct obstack *__o1 = (OBSTACK); \ 438130812Smarcel *(const void **) __o1->next_free = (aptr); \ 439130812Smarcel __o1->next_free += sizeof (const void *); \ 440130812Smarcel (void) 0; }) 441130812Smarcel 442130812Smarcel# define obstack_int_grow_fast(OBSTACK,aint) \ 443130812Smarcel__extension__ \ 444130812Smarcel({ struct obstack *__o1 = (OBSTACK); \ 445130812Smarcel *(int *) __o1->next_free = (aint); \ 446130812Smarcel __o1->next_free += sizeof (int); \ 447130812Smarcel (void) 0; }) 448130812Smarcel 449130812Smarcel# define obstack_blank(OBSTACK,length) \ 450130812Smarcel__extension__ \ 451130812Smarcel({ struct obstack *__o = (OBSTACK); \ 452130812Smarcel int __len = (length); \ 453130812Smarcel if (__o->chunk_limit - __o->next_free < __len) \ 454130812Smarcel _obstack_newchunk (__o, __len); \ 455130812Smarcel obstack_blank_fast (__o, __len); \ 456130812Smarcel (void) 0; }) 457130812Smarcel 458130812Smarcel# define obstack_alloc(OBSTACK,length) \ 459130812Smarcel__extension__ \ 460130812Smarcel({ struct obstack *__h = (OBSTACK); \ 461130812Smarcel obstack_blank (__h, (length)); \ 462130812Smarcel obstack_finish (__h); }) 463130812Smarcel 464130812Smarcel# define obstack_copy(OBSTACK,where,length) \ 465130812Smarcel__extension__ \ 466130812Smarcel({ struct obstack *__h = (OBSTACK); \ 467130812Smarcel obstack_grow (__h, (where), (length)); \ 468130812Smarcel obstack_finish (__h); }) 469130812Smarcel 470130812Smarcel# define obstack_copy0(OBSTACK,where,length) \ 471130812Smarcel__extension__ \ 472130812Smarcel({ struct obstack *__h = (OBSTACK); \ 473130812Smarcel obstack_grow0 (__h, (where), (length)); \ 474130812Smarcel obstack_finish (__h); }) 475130812Smarcel 476130812Smarcel/* The local variable is named __o1 to avoid a name conflict 477130812Smarcel when obstack_blank is called. */ 478130812Smarcel# define obstack_finish(OBSTACK) \ 479130812Smarcel__extension__ \ 480130812Smarcel({ struct obstack *__o1 = (OBSTACK); \ 481130812Smarcel void *value; \ 482130812Smarcel value = (void *) __o1->object_base; \ 483130812Smarcel if (__o1->next_free == value) \ 484130812Smarcel __o1->maybe_empty_object = 1; \ 485130812Smarcel __o1->next_free \ 486130812Smarcel = __INT_TO_PTR ((__PTR_TO_INT (__o1->next_free)+__o1->alignment_mask)\ 487130812Smarcel & ~ (__o1->alignment_mask)); \ 488130812Smarcel if (__o1->next_free - (char *)__o1->chunk \ 489130812Smarcel > __o1->chunk_limit - (char *)__o1->chunk) \ 490130812Smarcel __o1->next_free = __o1->chunk_limit; \ 491130812Smarcel __o1->object_base = __o1->next_free; \ 492130812Smarcel value; }) 493130812Smarcel 494130812Smarcel# define obstack_free(OBSTACK, OBJ) \ 495130812Smarcel__extension__ \ 496130812Smarcel({ struct obstack *__o = (OBSTACK); \ 497130812Smarcel void *__obj = (OBJ); \ 498130812Smarcel if (__obj > (void *)__o->chunk && __obj < (void *)__o->chunk_limit) \ 499130812Smarcel __o->next_free = __o->object_base = __obj; \ 500130812Smarcel else (obstack_free) (__o, __obj); }) 501130812Smarcel 502130812Smarcel#else /* not __GNUC__ or not __STDC__ */ 503130812Smarcel 504130812Smarcel# define obstack_object_size(h) \ 505130812Smarcel (unsigned) ((h)->next_free - (h)->object_base) 506130812Smarcel 507130812Smarcel# define obstack_room(h) \ 508130812Smarcel (unsigned) ((h)->chunk_limit - (h)->next_free) 509130812Smarcel 510130812Smarcel# define obstack_empty_p(h) \ 511130812Smarcel ((h)->chunk->prev == 0 && (h)->next_free - (h)->chunk->contents == 0) 512130812Smarcel 513130812Smarcel/* Note that the call to _obstack_newchunk is enclosed in (..., 0) 514130812Smarcel so that we can avoid having void expressions 515130812Smarcel in the arms of the conditional expression. 516130812Smarcel Casting the third operand to void was tried before, 517130812Smarcel but some compilers won't accept it. */ 518130812Smarcel 519130812Smarcel# define obstack_make_room(h,length) \ 520130812Smarcel( (h)->temp = (length), \ 521130812Smarcel (((h)->next_free + (h)->temp > (h)->chunk_limit) \ 522130812Smarcel ? (_obstack_newchunk ((h), (h)->temp), 0) : 0)) 523130812Smarcel 524130812Smarcel# define obstack_grow(h,where,length) \ 525130812Smarcel( (h)->temp = (length), \ 526130812Smarcel (((h)->next_free + (h)->temp > (h)->chunk_limit) \ 527130812Smarcel ? (_obstack_newchunk ((h), (h)->temp), 0) : 0), \ 528130812Smarcel _obstack_memcpy ((h)->next_free, (where), (h)->temp), \ 529130812Smarcel (h)->next_free += (h)->temp) 530130812Smarcel 531130812Smarcel# define obstack_grow0(h,where,length) \ 532130812Smarcel( (h)->temp = (length), \ 533130812Smarcel (((h)->next_free + (h)->temp + 1 > (h)->chunk_limit) \ 534130812Smarcel ? (_obstack_newchunk ((h), (h)->temp + 1), 0) : 0), \ 535130812Smarcel _obstack_memcpy ((h)->next_free, (where), (h)->temp), \ 536130812Smarcel (h)->next_free += (h)->temp, \ 537130812Smarcel *((h)->next_free)++ = 0) 538130812Smarcel 539130812Smarcel# define obstack_1grow(h,datum) \ 540130812Smarcel( (((h)->next_free + 1 > (h)->chunk_limit) \ 541130812Smarcel ? (_obstack_newchunk ((h), 1), 0) : 0), \ 542130812Smarcel obstack_1grow_fast (h, datum)) 543130812Smarcel 544130812Smarcel# define obstack_ptr_grow(h,datum) \ 545130812Smarcel( (((h)->next_free + sizeof (char *) > (h)->chunk_limit) \ 546130812Smarcel ? (_obstack_newchunk ((h), sizeof (char *)), 0) : 0), \ 547130812Smarcel obstack_ptr_grow_fast (h, datum)) 548130812Smarcel 549130812Smarcel# define obstack_int_grow(h,datum) \ 550130812Smarcel( (((h)->next_free + sizeof (int) > (h)->chunk_limit) \ 551130812Smarcel ? (_obstack_newchunk ((h), sizeof (int)), 0) : 0), \ 552130812Smarcel obstack_int_grow_fast (h, datum)) 553130812Smarcel 554130812Smarcel# define obstack_ptr_grow_fast(h,aptr) \ 555130812Smarcel (((const void **) ((h)->next_free += sizeof (void *)))[-1] = (aptr)) 556130812Smarcel 557130812Smarcel# define obstack_int_grow_fast(h,aint) \ 558130812Smarcel (((int *) ((h)->next_free += sizeof (int)))[-1] = (aptr)) 559130812Smarcel 560130812Smarcel# define obstack_blank(h,length) \ 561130812Smarcel( (h)->temp = (length), \ 562130812Smarcel (((h)->chunk_limit - (h)->next_free < (h)->temp) \ 563130812Smarcel ? (_obstack_newchunk ((h), (h)->temp), 0) : 0), \ 564130812Smarcel obstack_blank_fast (h, (h)->temp)) 565130812Smarcel 566130812Smarcel# define obstack_alloc(h,length) \ 567130812Smarcel (obstack_blank ((h), (length)), obstack_finish ((h))) 568130812Smarcel 569130812Smarcel# define obstack_copy(h,where,length) \ 570130812Smarcel (obstack_grow ((h), (where), (length)), obstack_finish ((h))) 571130812Smarcel 572130812Smarcel# define obstack_copy0(h,where,length) \ 573130812Smarcel (obstack_grow0 ((h), (where), (length)), obstack_finish ((h))) 574130812Smarcel 575130812Smarcel# define obstack_finish(h) \ 576130812Smarcel( ((h)->next_free == (h)->object_base \ 577130812Smarcel ? (((h)->maybe_empty_object = 1), 0) \ 578130812Smarcel : 0), \ 579130812Smarcel (h)->temp = __PTR_TO_INT ((h)->object_base), \ 580130812Smarcel (h)->next_free \ 581130812Smarcel = __INT_TO_PTR ((__PTR_TO_INT ((h)->next_free)+(h)->alignment_mask) \ 582130812Smarcel & ~ ((h)->alignment_mask)), \ 583130812Smarcel (((h)->next_free - (char *) (h)->chunk \ 584130812Smarcel > (h)->chunk_limit - (char *) (h)->chunk) \ 585130812Smarcel ? ((h)->next_free = (h)->chunk_limit) : 0), \ 586130812Smarcel (h)->object_base = (h)->next_free, \ 587130812Smarcel __INT_TO_PTR ((h)->temp)) 588130812Smarcel 589130812Smarcel# if defined __STDC__ && __STDC__ 590130812Smarcel# define obstack_free(h,obj) \ 591130812Smarcel( (h)->temp = (char *) (obj) - (char *) (h)->chunk, \ 592130812Smarcel (((h)->temp > 0 && (h)->temp < (h)->chunk_limit - (char *) (h)->chunk)\ 593130812Smarcel ? (int) ((h)->next_free = (h)->object_base \ 594130812Smarcel = (h)->temp + (char *) (h)->chunk) \ 595130812Smarcel : (((obstack_free) ((h), (h)->temp + (char *) (h)->chunk), 0), 0))) 596130812Smarcel# else 597130812Smarcel# define obstack_free(h,obj) \ 598130812Smarcel( (h)->temp = (char *) (obj) - (char *) (h)->chunk, \ 599130812Smarcel (((h)->temp > 0 && (h)->temp < (h)->chunk_limit - (char *) (h)->chunk)\ 600130812Smarcel ? (int) ((h)->next_free = (h)->object_base \ 601130812Smarcel = (h)->temp + (char *) (h)->chunk) \ 602130812Smarcel : (_obstack_free ((h), (h)->temp + (char *) (h)->chunk), 0))) 603130812Smarcel# endif 604130812Smarcel 605130812Smarcel#endif /* not __GNUC__ or not __STDC__ */ 606130812Smarcel 607130812Smarcel#ifdef __cplusplus 608130812Smarcel} /* C++ */ 609130812Smarcel#endif 610130812Smarcel 611130812Smarcel#endif /* obstack.h */ 612