198b9484cSchristos /* obstack.h - object stack macros 2*e663ba6eSchristos Copyright (C) 1988-2024 Free Software Foundation, Inc. 3ba340e45Schristos This file is part of the GNU C Library. 498b9484cSchristos 5ba340e45Schristos The GNU C Library is free software; you can redistribute it and/or 6ba340e45Schristos modify it under the terms of the GNU Lesser General Public 7ba340e45Schristos License as published by the Free Software Foundation; either 8ba340e45Schristos version 2.1 of the License, or (at your option) any later version. 998b9484cSchristos 10ba340e45Schristos The GNU C Library is distributed in the hope that it will be useful, 1198b9484cSchristos but WITHOUT ANY WARRANTY; without even the implied warranty of 12ba340e45Schristos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13ba340e45Schristos Lesser General Public License for more details. 1498b9484cSchristos 15ba340e45Schristos You should have received a copy of the GNU Lesser General Public 16ba340e45Schristos License along with the GNU C Library; if not, see 17ba340e45Schristos <http://www.gnu.org/licenses/>. */ 1898b9484cSchristos 1998b9484cSchristos /* Summary: 2098b9484cSchristos 2198b9484cSchristos All the apparent functions defined here are macros. The idea 2298b9484cSchristos is that you would use these pre-tested macros to solve a 2398b9484cSchristos very specific set of problems, and they would run fast. 2498b9484cSchristos Caution: no side-effects in arguments please!! They may be 2598b9484cSchristos evaluated MANY times!! 2698b9484cSchristos 2798b9484cSchristos These macros operate a stack of objects. Each object starts life 2898b9484cSchristos small, and may grow to maturity. (Consider building a word syllable 2998b9484cSchristos by syllable.) An object can move while it is growing. Once it has 3098b9484cSchristos been "finished" it never changes address again. So the "top of the 3198b9484cSchristos stack" is typically an immature growing object, while the rest of the 3298b9484cSchristos stack is of mature, fixed size and fixed address objects. 3398b9484cSchristos 3498b9484cSchristos These routines grab large chunks of memory, using a function you 35ba340e45Schristos supply, called 'obstack_chunk_alloc'. On occasion, they free chunks, 36ba340e45Schristos by calling 'obstack_chunk_free'. You must define them and declare 3798b9484cSchristos them before using any obstack macros. 3898b9484cSchristos 39ba340e45Schristos Each independent stack is represented by a 'struct obstack'. 4098b9484cSchristos Each of the obstack macros expects a pointer to such a structure 4198b9484cSchristos as the first argument. 4298b9484cSchristos 4398b9484cSchristos One motivation for this package is the problem of growing char strings 4498b9484cSchristos in symbol tables. Unless you are "fascist pig with a read-only mind" 4598b9484cSchristos --Gosper's immortal quote from HAKMEM item 154, out of context--you 4698b9484cSchristos would not like to put any arbitrary upper limit on the length of your 4798b9484cSchristos symbols. 4898b9484cSchristos 4998b9484cSchristos In practice this often means you will build many short symbols and a 5098b9484cSchristos few long symbols. At the time you are reading a symbol you don't know 5198b9484cSchristos how long it is. One traditional method is to read a symbol into a 5298b9484cSchristos buffer, realloc()ating the buffer every time you try to read a symbol 5398b9484cSchristos that is longer than the buffer. This is beaut, but you still will 5498b9484cSchristos want to copy the symbol from the buffer to a more permanent 5598b9484cSchristos symbol-table entry say about half the time. 5698b9484cSchristos 5798b9484cSchristos With obstacks, you can work differently. Use one obstack for all symbol 5898b9484cSchristos names. As you read a symbol, grow the name in the obstack gradually. 5998b9484cSchristos When the name is complete, finalize it. Then, if the symbol exists already, 6098b9484cSchristos free the newly read name. 6198b9484cSchristos 6298b9484cSchristos The way we do this is to take a large chunk, allocating memory from 6398b9484cSchristos low addresses. When you want to build a symbol in the chunk you just 6498b9484cSchristos add chars above the current "high water mark" in the chunk. When you 6598b9484cSchristos have finished adding chars, because you got to the end of the symbol, 6698b9484cSchristos you know how long the chars are, and you can create a new object. 6798b9484cSchristos Mostly the chars will not burst over the highest address of the chunk, 6898b9484cSchristos because you would typically expect a chunk to be (say) 100 times as 6998b9484cSchristos long as an average object. 7098b9484cSchristos 7198b9484cSchristos In case that isn't clear, when we have enough chars to make up 7298b9484cSchristos the object, THEY ARE ALREADY CONTIGUOUS IN THE CHUNK (guaranteed) 7398b9484cSchristos so we just point to it where it lies. No moving of chars is 7498b9484cSchristos needed and this is the second win: potentially long strings need 7598b9484cSchristos never be explicitly shuffled. Once an object is formed, it does not 7698b9484cSchristos change its address during its lifetime. 7798b9484cSchristos 7898b9484cSchristos When the chars burst over a chunk boundary, we allocate a larger 7998b9484cSchristos chunk, and then copy the partly formed object from the end of the old 8098b9484cSchristos chunk to the beginning of the new larger chunk. We then carry on 8198b9484cSchristos accreting characters to the end of the object as we normally would. 8298b9484cSchristos 8398b9484cSchristos A special macro is provided to add a single char at a time to a 8498b9484cSchristos growing object. This allows the use of register variables, which 8598b9484cSchristos break the ordinary 'growth' macro. 8698b9484cSchristos 8798b9484cSchristos Summary: 8898b9484cSchristos We allocate large chunks. 8998b9484cSchristos We carve out one object at a time from the current chunk. 9098b9484cSchristos Once carved, an object never moves. 9198b9484cSchristos We are free to append data of any size to the currently 9298b9484cSchristos growing object. 9398b9484cSchristos Exactly one object is growing in an obstack at any one time. 9498b9484cSchristos You can run one obstack per control block. 9598b9484cSchristos You may have as many control blocks as you dare. 96ba340e45Schristos Because of the way we do it, you can "unwind" an obstack 9798b9484cSchristos back to a previous state. (You may remove objects much 9898b9484cSchristos as you would with a stack.) 9998b9484cSchristos */ 10098b9484cSchristos 10198b9484cSchristos 10298b9484cSchristos /* Don't do the contents of this file more than once. */ 10398b9484cSchristos 10498b9484cSchristos #ifndef _OBSTACK_H 10598b9484cSchristos #define _OBSTACK_H 1 10698b9484cSchristos 107ba340e45Schristos #ifndef _OBSTACK_INTERFACE_VERSION 108ba340e45Schristos # define _OBSTACK_INTERFACE_VERSION 2 109ba340e45Schristos #endif 110ba340e45Schristos 111ba340e45Schristos #include <stddef.h> /* For size_t and ptrdiff_t. */ 112ba340e45Schristos #include <string.h> /* For __GNU_LIBRARY__, and memcpy. */ 113ba340e45Schristos 114ba340e45Schristos #if _OBSTACK_INTERFACE_VERSION == 1 115ba340e45Schristos /* For binary compatibility with obstack version 1, which used "int" 116ba340e45Schristos and "long" for these two types. */ 117ba340e45Schristos # define _OBSTACK_SIZE_T unsigned int 118ba340e45Schristos # define _CHUNK_SIZE_T unsigned long 119ba340e45Schristos # define _OBSTACK_CAST(type, expr) ((type) (expr)) 120ba340e45Schristos #else 121ba340e45Schristos /* Version 2 with sane types, especially for 64-bit hosts. */ 122ba340e45Schristos # define _OBSTACK_SIZE_T size_t 123ba340e45Schristos # define _CHUNK_SIZE_T size_t 124ba340e45Schristos # define _OBSTACK_CAST(type, expr) (expr) 125ba340e45Schristos #endif 126ba340e45Schristos 127ba340e45Schristos /* If B is the base of an object addressed by P, return the result of 128ba340e45Schristos aligning P to the next multiple of A + 1. B and P must be of type 129ba340e45Schristos char *. A + 1 must be a power of 2. */ 130ba340e45Schristos 131ba340e45Schristos #define __BPTR_ALIGN(B, P, A) ((B) + (((P) - (B) + (A)) & ~(A))) 132ba340e45Schristos 133ba340e45Schristos /* Similar to __BPTR_ALIGN (B, P, A), except optimize the common case 134ba340e45Schristos where pointers can be converted to integers, aligned as integers, 135ba340e45Schristos and converted back again. If ptrdiff_t is narrower than a 136ba340e45Schristos pointer (e.g., the AS/400), play it safe and compute the alignment 137ba340e45Schristos relative to B. Otherwise, use the faster strategy of computing the 138ba340e45Schristos alignment relative to 0. */ 139ba340e45Schristos 140ba340e45Schristos #define __PTR_ALIGN(B, P, A) \ 1414b169a6bSchristos (sizeof (ptrdiff_t) < sizeof (void *) ? __BPTR_ALIGN (B, P, A) \ 1424b169a6bSchristos : (char *) (((ptrdiff_t) (P) + (A)) & ~(A))) 143ba340e45Schristos 144ba340e45Schristos #ifndef __attribute_pure__ 145ba340e45Schristos # if defined __GNUC_MINOR__ && __GNUC__ * 1000 + __GNUC_MINOR__ >= 2096 146ba340e45Schristos # define __attribute_pure__ __attribute__ ((__pure__)) 147ba340e45Schristos # else 148ba340e45Schristos # define __attribute_pure__ 149ba340e45Schristos # endif 150ba340e45Schristos #endif 151ba340e45Schristos 15298b9484cSchristos #ifdef __cplusplus 15398b9484cSchristos extern "C" { 15498b9484cSchristos #endif 15598b9484cSchristos 15698b9484cSchristos struct _obstack_chunk /* Lives at front of each chunk. */ 15798b9484cSchristos { 15898b9484cSchristos char *limit; /* 1 past end of this chunk */ 15998b9484cSchristos struct _obstack_chunk *prev; /* address of prior chunk or NULL */ 16098b9484cSchristos char contents[4]; /* objects begin here */ 16198b9484cSchristos }; 16298b9484cSchristos 16398b9484cSchristos struct obstack /* control current object in current chunk */ 16498b9484cSchristos { 165ba340e45Schristos _CHUNK_SIZE_T chunk_size; /* preferred size to allocate chunks in */ 16698b9484cSchristos struct _obstack_chunk *chunk; /* address of current struct obstack_chunk */ 16798b9484cSchristos char *object_base; /* address of object we are building */ 16898b9484cSchristos char *next_free; /* where to add next char to current object */ 16998b9484cSchristos char *chunk_limit; /* address of char after current chunk */ 170ba340e45Schristos union 171ba340e45Schristos { 172ba340e45Schristos _OBSTACK_SIZE_T i; 173ba340e45Schristos void *p; 174ba340e45Schristos } temp; /* Temporary for some macros. */ 175ba340e45Schristos _OBSTACK_SIZE_T alignment_mask; /* Mask of alignment for each object. */ 176ba340e45Schristos 177ba340e45Schristos /* These prototypes vary based on 'use_extra_arg'. */ 178ba340e45Schristos union 179ba340e45Schristos { 180ba340e45Schristos void *(*plain) (size_t); 181ba340e45Schristos void *(*extra) (void *, size_t); 182ba340e45Schristos } chunkfun; 183ba340e45Schristos union 184ba340e45Schristos { 185ba340e45Schristos void (*plain) (void *); 186ba340e45Schristos void (*extra) (void *, void *); 187ba340e45Schristos } freefun; 188ba340e45Schristos 18998b9484cSchristos void *extra_arg; /* first arg for chunk alloc/dealloc funcs */ 19098b9484cSchristos unsigned use_extra_arg : 1; /* chunk alloc/dealloc funcs take extra arg */ 19198b9484cSchristos unsigned maybe_empty_object : 1; /* There is a possibility that the current 19298b9484cSchristos chunk contains a zero-length object. This 19398b9484cSchristos prevents freeing the chunk if we allocate 19498b9484cSchristos a bigger chunk to replace it. */ 19598b9484cSchristos unsigned alloc_failed : 1; /* No longer used, as we now call the failed 19698b9484cSchristos handler on error, but retained for binary 19798b9484cSchristos compatibility. */ 19898b9484cSchristos }; 19998b9484cSchristos 20098b9484cSchristos /* Declare the external functions we use; they are in obstack.c. */ 20198b9484cSchristos 202ba340e45Schristos extern void _obstack_newchunk (struct obstack *, _OBSTACK_SIZE_T); 20398b9484cSchristos extern void _obstack_free (struct obstack *, void *); 204ba340e45Schristos extern int _obstack_begin (struct obstack *, 205ba340e45Schristos _OBSTACK_SIZE_T, _OBSTACK_SIZE_T, 206ba340e45Schristos void *(*) (size_t), void (*) (void *)); 207ba340e45Schristos extern int _obstack_begin_1 (struct obstack *, 208ba340e45Schristos _OBSTACK_SIZE_T, _OBSTACK_SIZE_T, 209ba340e45Schristos void *(*) (void *, size_t), 21098b9484cSchristos void (*) (void *, void *), void *); 211ba340e45Schristos extern _OBSTACK_SIZE_T _obstack_memory_used (struct obstack *) 212ba340e45Schristos __attribute_pure__; 21398b9484cSchristos 21498b9484cSchristos 215ba340e45Schristos /* Error handler called when 'obstack_chunk_alloc' failed to allocate 216ba340e45Schristos more memory. This can be set to a user defined function which 217ba340e45Schristos should either abort gracefully or use longjump - but shouldn't 218ba340e45Schristos return. The default action is to print a message and abort. */ 21998b9484cSchristos extern void (*obstack_alloc_failed_handler) (void); 22098b9484cSchristos 221ba340e45Schristos /* Exit value used when 'print_and_abort' is used. */ 22298b9484cSchristos extern int obstack_exit_failure; 223ba340e45Schristos 22498b9484cSchristos /* Pointer to beginning of object being allocated or to be allocated next. 22598b9484cSchristos Note that this might not be the final address of the object 22698b9484cSchristos because a new chunk might be needed to hold the final size. */ 22798b9484cSchristos 228ba340e45Schristos #define obstack_base(h) ((void *) (h)->object_base) 22998b9484cSchristos 23098b9484cSchristos /* Size for allocating ordinary chunks. */ 23198b9484cSchristos 23298b9484cSchristos #define obstack_chunk_size(h) ((h)->chunk_size) 23398b9484cSchristos 23498b9484cSchristos /* Pointer to next byte not yet allocated in current chunk. */ 23598b9484cSchristos 236ba340e45Schristos #define obstack_next_free(h) ((void *) (h)->next_free) 23798b9484cSchristos 23898b9484cSchristos /* Mask specifying low bits that should be clear in address of an object. */ 23998b9484cSchristos 24098b9484cSchristos #define obstack_alignment_mask(h) ((h)->alignment_mask) 24198b9484cSchristos 242ba340e45Schristos /* To prevent prototype warnings provide complete argument list. */ 24398b9484cSchristos #define obstack_init(h) \ 24498b9484cSchristos _obstack_begin ((h), 0, 0, \ 245ba340e45Schristos _OBSTACK_CAST (void *(*) (size_t), obstack_chunk_alloc), \ 246ba340e45Schristos _OBSTACK_CAST (void (*) (void *), obstack_chunk_free)) 24798b9484cSchristos 24898b9484cSchristos #define obstack_begin(h, size) \ 24998b9484cSchristos _obstack_begin ((h), (size), 0, \ 250ba340e45Schristos _OBSTACK_CAST (void *(*) (size_t), obstack_chunk_alloc), \ 251ba340e45Schristos _OBSTACK_CAST (void (*) (void *), obstack_chunk_free)) 25298b9484cSchristos 25398b9484cSchristos #define obstack_specify_allocation(h, size, alignment, chunkfun, freefun) \ 25498b9484cSchristos _obstack_begin ((h), (size), (alignment), \ 255ba340e45Schristos _OBSTACK_CAST (void *(*) (size_t), chunkfun), \ 256ba340e45Schristos _OBSTACK_CAST (void (*) (void *), freefun)) 25798b9484cSchristos 25898b9484cSchristos #define obstack_specify_allocation_with_arg(h, size, alignment, chunkfun, freefun, arg) \ 25998b9484cSchristos _obstack_begin_1 ((h), (size), (alignment), \ 260ba340e45Schristos _OBSTACK_CAST (void *(*) (void *, size_t), chunkfun), \ 261ba340e45Schristos _OBSTACK_CAST (void (*) (void *, void *), freefun), arg) 26298b9484cSchristos 26398b9484cSchristos #define obstack_chunkfun(h, newchunkfun) \ 264ba340e45Schristos ((void) ((h)->chunkfun.extra = (void *(*) (void *, size_t)) (newchunkfun))) 26598b9484cSchristos 26698b9484cSchristos #define obstack_freefun(h, newfreefun) \ 267ba340e45Schristos ((void) ((h)->freefun.extra = (void *(*) (void *, void *)) (newfreefun))) 26898b9484cSchristos 269ba340e45Schristos #define obstack_1grow_fast(h, achar) ((void) (*((h)->next_free)++ = (achar))) 27098b9484cSchristos 271ba340e45Schristos #define obstack_blank_fast(h, n) ((void) ((h)->next_free += (n))) 27298b9484cSchristos 27398b9484cSchristos #define obstack_memory_used(h) _obstack_memory_used (h) 274ba340e45Schristos 275ba340e45Schristos #if defined __GNUC__ 276ba340e45Schristos # if !defined __GNUC_MINOR__ || __GNUC__ * 1000 + __GNUC_MINOR__ < 2008 27798b9484cSchristos # define __extension__ 27898b9484cSchristos # endif 27998b9484cSchristos 28098b9484cSchristos /* For GNU C, if not -traditional, 28198b9484cSchristos we can define these macros to compute all args only once 28298b9484cSchristos without using a global variable. 283ba340e45Schristos Also, we can avoid using the 'temp' slot, to make faster code. */ 28498b9484cSchristos 28598b9484cSchristos # define obstack_object_size(OBSTACK) \ 28698b9484cSchristos __extension__ \ 287ba340e45Schristos ({ struct obstack const *__o = (OBSTACK); \ 288ba340e45Schristos (_OBSTACK_SIZE_T) (__o->next_free - __o->object_base); }) 28998b9484cSchristos 290ba340e45Schristos /* The local variable is named __o1 to avoid a shadowed variable 291ba340e45Schristos warning when invoked from other obstack macros. */ 29298b9484cSchristos # define obstack_room(OBSTACK) \ 29398b9484cSchristos __extension__ \ 294ba340e45Schristos ({ struct obstack const *__o1 = (OBSTACK); \ 295ba340e45Schristos (_OBSTACK_SIZE_T) (__o1->chunk_limit - __o1->next_free); }) 29698b9484cSchristos 29798b9484cSchristos # define obstack_make_room(OBSTACK, length) \ 29898b9484cSchristos __extension__ \ 29998b9484cSchristos ({ struct obstack *__o = (OBSTACK); \ 300ba340e45Schristos _OBSTACK_SIZE_T __len = (length); \ 301ba340e45Schristos if (obstack_room (__o) < __len) \ 30298b9484cSchristos _obstack_newchunk (__o, __len); \ 30398b9484cSchristos (void) 0; }) 30498b9484cSchristos 30598b9484cSchristos # define obstack_empty_p(OBSTACK) \ 30698b9484cSchristos __extension__ \ 307ba340e45Schristos ({ struct obstack const *__o = (OBSTACK); \ 308ba340e45Schristos (__o->chunk->prev == 0 \ 309ba340e45Schristos && __o->next_free == __PTR_ALIGN ((char *) __o->chunk, \ 310ba340e45Schristos __o->chunk->contents, \ 311ba340e45Schristos __o->alignment_mask)); }) 31298b9484cSchristos 31398b9484cSchristos # define obstack_grow(OBSTACK, where, length) \ 31498b9484cSchristos __extension__ \ 31598b9484cSchristos ({ struct obstack *__o = (OBSTACK); \ 316ba340e45Schristos _OBSTACK_SIZE_T __len = (length); \ 317ba340e45Schristos if (obstack_room (__o) < __len) \ 31898b9484cSchristos _obstack_newchunk (__o, __len); \ 319ba340e45Schristos memcpy (__o->next_free, where, __len); \ 32098b9484cSchristos __o->next_free += __len; \ 32198b9484cSchristos (void) 0; }) 32298b9484cSchristos 32398b9484cSchristos # define obstack_grow0(OBSTACK, where, length) \ 32498b9484cSchristos __extension__ \ 32598b9484cSchristos ({ struct obstack *__o = (OBSTACK); \ 326ba340e45Schristos _OBSTACK_SIZE_T __len = (length); \ 327ba340e45Schristos if (obstack_room (__o) < __len + 1) \ 32898b9484cSchristos _obstack_newchunk (__o, __len + 1); \ 329ba340e45Schristos memcpy (__o->next_free, where, __len); \ 33098b9484cSchristos __o->next_free += __len; \ 33198b9484cSchristos *(__o->next_free)++ = 0; \ 33298b9484cSchristos (void) 0; }) 33398b9484cSchristos 33498b9484cSchristos # define obstack_1grow(OBSTACK, datum) \ 33598b9484cSchristos __extension__ \ 33698b9484cSchristos ({ struct obstack *__o = (OBSTACK); \ 337ba340e45Schristos if (obstack_room (__o) < 1) \ 33898b9484cSchristos _obstack_newchunk (__o, 1); \ 339ba340e45Schristos obstack_1grow_fast (__o, datum); }) 34098b9484cSchristos 341ba340e45Schristos /* These assume that the obstack alignment is good enough for pointers 342ba340e45Schristos or ints, and that the data added so far to the current object 34398b9484cSchristos shares that much alignment. */ 34498b9484cSchristos 34598b9484cSchristos # define obstack_ptr_grow(OBSTACK, datum) \ 34698b9484cSchristos __extension__ \ 34798b9484cSchristos ({ struct obstack *__o = (OBSTACK); \ 348ba340e45Schristos if (obstack_room (__o) < sizeof (void *)) \ 34998b9484cSchristos _obstack_newchunk (__o, sizeof (void *)); \ 35098b9484cSchristos obstack_ptr_grow_fast (__o, datum); }) 35198b9484cSchristos 35298b9484cSchristos # define obstack_int_grow(OBSTACK, datum) \ 35398b9484cSchristos __extension__ \ 35498b9484cSchristos ({ struct obstack *__o = (OBSTACK); \ 355ba340e45Schristos if (obstack_room (__o) < sizeof (int)) \ 35698b9484cSchristos _obstack_newchunk (__o, sizeof (int)); \ 35798b9484cSchristos obstack_int_grow_fast (__o, datum); }) 35898b9484cSchristos 35998b9484cSchristos # define obstack_ptr_grow_fast(OBSTACK, aptr) \ 36098b9484cSchristos __extension__ \ 36198b9484cSchristos ({ struct obstack *__o1 = (OBSTACK); \ 362ba340e45Schristos void *__p1 = __o1->next_free; \ 363ba340e45Schristos *(const void **) __p1 = (aptr); \ 36498b9484cSchristos __o1->next_free += sizeof (const void *); \ 36598b9484cSchristos (void) 0; }) 36698b9484cSchristos 36798b9484cSchristos # define obstack_int_grow_fast(OBSTACK, aint) \ 36898b9484cSchristos __extension__ \ 36998b9484cSchristos ({ struct obstack *__o1 = (OBSTACK); \ 370ba340e45Schristos void *__p1 = __o1->next_free; \ 371ba340e45Schristos *(int *) __p1 = (aint); \ 37298b9484cSchristos __o1->next_free += sizeof (int); \ 37398b9484cSchristos (void) 0; }) 37498b9484cSchristos 37598b9484cSchristos # define obstack_blank(OBSTACK, length) \ 37698b9484cSchristos __extension__ \ 37798b9484cSchristos ({ struct obstack *__o = (OBSTACK); \ 378ba340e45Schristos _OBSTACK_SIZE_T __len = (length); \ 379ba340e45Schristos if (obstack_room (__o) < __len) \ 38098b9484cSchristos _obstack_newchunk (__o, __len); \ 381ba340e45Schristos obstack_blank_fast (__o, __len); }) 38298b9484cSchristos 38398b9484cSchristos # define obstack_alloc(OBSTACK, length) \ 38498b9484cSchristos __extension__ \ 38598b9484cSchristos ({ struct obstack *__h = (OBSTACK); \ 38698b9484cSchristos obstack_blank (__h, (length)); \ 38798b9484cSchristos obstack_finish (__h); }) 38898b9484cSchristos 38998b9484cSchristos # define obstack_copy(OBSTACK, where, length) \ 39098b9484cSchristos __extension__ \ 39198b9484cSchristos ({ struct obstack *__h = (OBSTACK); \ 39298b9484cSchristos obstack_grow (__h, (where), (length)); \ 39398b9484cSchristos obstack_finish (__h); }) 39498b9484cSchristos 39598b9484cSchristos # define obstack_copy0(OBSTACK, where, length) \ 39698b9484cSchristos __extension__ \ 39798b9484cSchristos ({ struct obstack *__h = (OBSTACK); \ 39898b9484cSchristos obstack_grow0 (__h, (where), (length)); \ 39998b9484cSchristos obstack_finish (__h); }) 40098b9484cSchristos 401ba340e45Schristos /* The local variable is named __o1 to avoid a shadowed variable 402ba340e45Schristos warning when invoked from other obstack macros, typically obstack_free. */ 40398b9484cSchristos # define obstack_finish(OBSTACK) \ 40498b9484cSchristos __extension__ \ 40598b9484cSchristos ({ struct obstack *__o1 = (OBSTACK); \ 406ba340e45Schristos void *__value = (void *) __o1->object_base; \ 407ba340e45Schristos if (__o1->next_free == __value) \ 40898b9484cSchristos __o1->maybe_empty_object = 1; \ 40998b9484cSchristos __o1->next_free \ 410ba340e45Schristos = __PTR_ALIGN (__o1->object_base, __o1->next_free, \ 411ba340e45Schristos __o1->alignment_mask); \ 412ba340e45Schristos if ((size_t) (__o1->next_free - (char *) __o1->chunk) \ 413ba340e45Schristos > (size_t) (__o1->chunk_limit - (char *) __o1->chunk)) \ 41498b9484cSchristos __o1->next_free = __o1->chunk_limit; \ 41598b9484cSchristos __o1->object_base = __o1->next_free; \ 416ba340e45Schristos __value; }) 41798b9484cSchristos 41898b9484cSchristos # define obstack_free(OBSTACK, OBJ) \ 41998b9484cSchristos __extension__ \ 42098b9484cSchristos ({ struct obstack *__o = (OBSTACK); \ 42198b9484cSchristos void *__obj = (void *) (OBJ); \ 42298b9484cSchristos if (__obj > (void *) __o->chunk && __obj < (void *) __o->chunk_limit) \ 42398b9484cSchristos __o->next_free = __o->object_base = (char *) __obj; \ 424ba340e45Schristos else \ 425ba340e45Schristos _obstack_free (__o, __obj); }) 426ba340e45Schristos 427ba340e45Schristos #else /* not __GNUC__ */ 42898b9484cSchristos 42998b9484cSchristos # define obstack_object_size(h) \ 430ba340e45Schristos ((_OBSTACK_SIZE_T) ((h)->next_free - (h)->object_base)) 43198b9484cSchristos 43298b9484cSchristos # define obstack_room(h) \ 433ba340e45Schristos ((_OBSTACK_SIZE_T) ((h)->chunk_limit - (h)->next_free)) 43498b9484cSchristos 43598b9484cSchristos # define obstack_empty_p(h) \ 436ba340e45Schristos ((h)->chunk->prev == 0 \ 437ba340e45Schristos && (h)->next_free == __PTR_ALIGN ((char *) (h)->chunk, \ 438ba340e45Schristos (h)->chunk->contents, \ 439ba340e45Schristos (h)->alignment_mask)) 44098b9484cSchristos 44198b9484cSchristos /* Note that the call to _obstack_newchunk is enclosed in (..., 0) 44298b9484cSchristos so that we can avoid having void expressions 44398b9484cSchristos in the arms of the conditional expression. 44498b9484cSchristos Casting the third operand to void was tried before, 44598b9484cSchristos but some compilers won't accept it. */ 44698b9484cSchristos 44798b9484cSchristos # define obstack_make_room(h, length) \ 448ba340e45Schristos ((h)->temp.i = (length), \ 449ba340e45Schristos ((obstack_room (h) < (h)->temp.i) \ 450ba340e45Schristos ? (_obstack_newchunk (h, (h)->temp.i), 0) : 0), \ 451ba340e45Schristos (void) 0) 45298b9484cSchristos 45398b9484cSchristos # define obstack_grow(h, where, length) \ 454ba340e45Schristos ((h)->temp.i = (length), \ 455ba340e45Schristos ((obstack_room (h) < (h)->temp.i) \ 456ba340e45Schristos ? (_obstack_newchunk ((h), (h)->temp.i), 0) : 0), \ 457ba340e45Schristos memcpy ((h)->next_free, where, (h)->temp.i), \ 458ba340e45Schristos (h)->next_free += (h)->temp.i, \ 459ba340e45Schristos (void) 0) 46098b9484cSchristos 46198b9484cSchristos # define obstack_grow0(h, where, length) \ 462ba340e45Schristos ((h)->temp.i = (length), \ 463ba340e45Schristos ((obstack_room (h) < (h)->temp.i + 1) \ 464ba340e45Schristos ? (_obstack_newchunk ((h), (h)->temp.i + 1), 0) : 0), \ 465ba340e45Schristos memcpy ((h)->next_free, where, (h)->temp.i), \ 466ba340e45Schristos (h)->next_free += (h)->temp.i, \ 467ba340e45Schristos *((h)->next_free)++ = 0, \ 468ba340e45Schristos (void) 0) 46998b9484cSchristos 47098b9484cSchristos # define obstack_1grow(h, datum) \ 471ba340e45Schristos (((obstack_room (h) < 1) \ 47298b9484cSchristos ? (_obstack_newchunk ((h), 1), 0) : 0), \ 47398b9484cSchristos obstack_1grow_fast (h, datum)) 47498b9484cSchristos 47598b9484cSchristos # define obstack_ptr_grow(h, datum) \ 476ba340e45Schristos (((obstack_room (h) < sizeof (char *)) \ 47798b9484cSchristos ? (_obstack_newchunk ((h), sizeof (char *)), 0) : 0), \ 47898b9484cSchristos obstack_ptr_grow_fast (h, datum)) 47998b9484cSchristos 48098b9484cSchristos # define obstack_int_grow(h, datum) \ 481ba340e45Schristos (((obstack_room (h) < sizeof (int)) \ 48298b9484cSchristos ? (_obstack_newchunk ((h), sizeof (int)), 0) : 0), \ 48398b9484cSchristos obstack_int_grow_fast (h, datum)) 48498b9484cSchristos 48598b9484cSchristos # define obstack_ptr_grow_fast(h, aptr) \ 486ba340e45Schristos (((const void **) ((h)->next_free += sizeof (void *)))[-1] = (aptr), \ 487ba340e45Schristos (void) 0) 48898b9484cSchristos 48998b9484cSchristos # define obstack_int_grow_fast(h, aint) \ 490ba340e45Schristos (((int *) ((h)->next_free += sizeof (int)))[-1] = (aint), \ 491ba340e45Schristos (void) 0) 49298b9484cSchristos 49398b9484cSchristos # define obstack_blank(h, length) \ 494ba340e45Schristos ((h)->temp.i = (length), \ 495ba340e45Schristos ((obstack_room (h) < (h)->temp.i) \ 496ba340e45Schristos ? (_obstack_newchunk ((h), (h)->temp.i), 0) : 0), \ 497ba340e45Schristos obstack_blank_fast (h, (h)->temp.i)) 49898b9484cSchristos 49998b9484cSchristos # define obstack_alloc(h, length) \ 50098b9484cSchristos (obstack_blank ((h), (length)), obstack_finish ((h))) 50198b9484cSchristos 50298b9484cSchristos # define obstack_copy(h, where, length) \ 50398b9484cSchristos (obstack_grow ((h), (where), (length)), obstack_finish ((h))) 50498b9484cSchristos 50598b9484cSchristos # define obstack_copy0(h, where, length) \ 50698b9484cSchristos (obstack_grow0 ((h), (where), (length)), obstack_finish ((h))) 50798b9484cSchristos 50898b9484cSchristos # define obstack_finish(h) \ 50998b9484cSchristos (((h)->next_free == (h)->object_base \ 51098b9484cSchristos ? (((h)->maybe_empty_object = 1), 0) \ 51198b9484cSchristos : 0), \ 512ba340e45Schristos (h)->temp.p = (h)->object_base, \ 51398b9484cSchristos (h)->next_free \ 514ba340e45Schristos = __PTR_ALIGN ((h)->object_base, (h)->next_free, \ 515ba340e45Schristos (h)->alignment_mask), \ 516ba340e45Schristos (((size_t) ((h)->next_free - (char *) (h)->chunk) \ 517ba340e45Schristos > (size_t) ((h)->chunk_limit - (char *) (h)->chunk)) \ 51898b9484cSchristos ? ((h)->next_free = (h)->chunk_limit) : 0), \ 51998b9484cSchristos (h)->object_base = (h)->next_free, \ 520ba340e45Schristos (h)->temp.p) 52198b9484cSchristos 52298b9484cSchristos # define obstack_free(h, obj) \ 523ba340e45Schristos ((h)->temp.p = (void *) (obj), \ 524ba340e45Schristos (((h)->temp.p > (void *) (h)->chunk \ 525ba340e45Schristos && (h)->temp.p < (void *) (h)->chunk_limit) \ 526ba340e45Schristos ? (void) ((h)->next_free = (h)->object_base = (char *) (h)->temp.p) \ 527ba340e45Schristos : _obstack_free ((h), (h)->temp.p))) 52898b9484cSchristos 529ba340e45Schristos #endif /* not __GNUC__ */ 53098b9484cSchristos 53198b9484cSchristos #ifdef __cplusplus 53298b9484cSchristos } /* C++ */ 53398b9484cSchristos #endif 53498b9484cSchristos 535ba340e45Schristos #endif /* _OBSTACK_H */ 536