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