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