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