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