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