glibc (2.38)

(root)/
include/
obstack.h
       1  /* obstack.h - object stack macros
       2     Copyright (C) 1988-2023 Free Software Foundation, Inc.
       3     This file is part of the GNU C Library.
       4  
       5     The GNU C Library is free software; you can redistribute it and/or
       6     modify it under the terms of the GNU Lesser General Public
       7     License as published by the Free Software Foundation; either
       8     version 2.1 of the License, or (at your option) any later version.
       9  
      10     The GNU C Library is distributed in the hope that it will be useful,
      11     but WITHOUT ANY WARRANTY; without even the implied warranty of
      12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      13     Lesser General Public License for more details.
      14  
      15     You should have received a copy of the GNU Lesser General Public
      16     License along with the GNU C Library; if not, see
      17     <https://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  /* We need the type of a pointer subtraction.  If __PTRDIFF_TYPE__ is
     108     defined, as with GNU C, use that; that way we don't pollute the
     109     namespace with <stddef.h>'s symbols.  Otherwise, include <stddef.h>
     110     and use ptrdiff_t.  */
     111  
     112  #ifdef __PTRDIFF_TYPE__
     113  # define PTR_INT_TYPE __PTRDIFF_TYPE__
     114  #else
     115  # include <stddef.h>
     116  # define PTR_INT_TYPE ptrdiff_t
     117  #endif
     118  
     119  /* If B is the base of an object addressed by P, return the result of
     120     aligning P to the next multiple of A + 1.  B and P must be of type
     121     char *.  A + 1 must be a power of 2.  */
     122  
     123  #define __BPTR_ALIGN(B, P, A) ((B) + (((P) - (B) + (A)) & ~(A)))
     124  
     125  /* Similar to _BPTR_ALIGN (B, P, A), except optimize the common case
     126     where pointers can be converted to integers, aligned as integers,
     127     and converted back again.  If PTR_INT_TYPE is narrower than a
     128     pointer (e.g., the AS/400), play it safe and compute the alignment
     129     relative to B.  Otherwise, use the faster strategy of computing the
     130     alignment relative to 0.  */
     131  
     132  #define __PTR_ALIGN(B, P, A)						      \
     133    __BPTR_ALIGN (sizeof (PTR_INT_TYPE) < sizeof (void *) ? (B) : (char *) 0, \
     134  		P, A)
     135  
     136  #include <string.h>
     137  
     138  #ifndef __attribute_pure__
     139  # define __attribute_pure__ _GL_ATTRIBUTE_PURE
     140  #endif
     141  
     142  #ifdef __cplusplus
     143  extern "C" {
     144  #endif
     145  
     146  struct _obstack_chunk           /* Lives at front of each chunk. */
     147  {
     148    char *limit;                  /* 1 past end of this chunk */
     149    struct _obstack_chunk *prev;  /* address of prior chunk or NULL */
     150    char contents[4];             /* objects begin here */
     151  };
     152  
     153  struct obstack          /* control current object in current chunk */
     154  {
     155    long chunk_size;              /* preferred size to allocate chunks in */
     156    struct _obstack_chunk *chunk; /* address of current struct obstack_chunk */
     157    char *object_base;            /* address of object we are building */
     158    char *next_free;              /* where to add next char to current object */
     159    char *chunk_limit;            /* address of char after current chunk */
     160    union
     161    {
     162      PTR_INT_TYPE tempint;
     163      void *tempptr;
     164    } temp;                       /* Temporary for some macros.  */
     165    int alignment_mask;           /* Mask of alignment for each object. */
     166    /* These prototypes vary based on 'use_extra_arg', and we use
     167       casts to the prototypeless function type in all assignments,
     168       but having prototypes here quiets -Wstrict-prototypes.  */
     169    struct _obstack_chunk *(*chunkfun) (void *, long);
     170    void (*freefun) (void *, struct _obstack_chunk *);
     171    void *extra_arg;              /* first arg for chunk alloc/dealloc funcs */
     172    unsigned use_extra_arg : 1;     /* chunk alloc/dealloc funcs take extra arg */
     173    unsigned maybe_empty_object : 1; /* There is a possibility that the current
     174  				      chunk contains a zero-length object.  This
     175  				      prevents freeing the chunk if we allocate
     176  				      a bigger chunk to replace it. */
     177    unsigned alloc_failed : 1;      /* No longer used, as we now call the failed
     178  				     handler on error, but retained for binary
     179  				     compatibility.  */
     180  };
     181  
     182  /* Declare the external functions we use; they are in obstack.c.  */
     183  
     184  extern void _obstack_newchunk (struct obstack *, int);
     185  extern int _obstack_begin (struct obstack *, int, int,
     186  			   void *(*)(long), void (*)(void *));
     187  extern int _obstack_begin_1 (struct obstack *, int, int,
     188  			     void *(*)(void *, long),
     189  			     void (*)(void *, void *), void *);
     190  extern int _obstack_memory_used (struct obstack *) __attribute_pure__;
     191  
     192  /* The default name of the function for freeing a chunk is 'obstack_free',
     193     but gnulib users can override this by defining '__obstack_free'.  */
     194  #ifndef __obstack_free
     195  # define __obstack_free obstack_free
     196  #endif
     197  extern void __obstack_free (struct obstack *, void *);
     198  
     199  
     200  /* Error handler called when 'obstack_chunk_alloc' failed to allocate
     201     more memory.  This can be set to a user defined function which
     202     should either abort gracefully or use longjump - but shouldn't
     203     return.  The default action is to print a message and abort.  */
     204  extern void (*obstack_alloc_failed_handler) (void);
     205  
     206  /* Exit value used when 'print_and_abort' is used.  */
     207  extern int obstack_exit_failure;
     208  
     209  /* Pointer to beginning of object being allocated or to be allocated next.
     210     Note that this might not be the final address of the object
     211     because a new chunk might be needed to hold the final size.  */
     212  
     213  #define obstack_base(h) ((void *) (h)->object_base)
     214  
     215  /* Size for allocating ordinary chunks.  */
     216  
     217  #define obstack_chunk_size(h) ((h)->chunk_size)
     218  
     219  /* Pointer to next byte not yet allocated in current chunk.  */
     220  
     221  #define obstack_next_free(h)    ((h)->next_free)
     222  
     223  /* Mask specifying low bits that should be clear in address of an object.  */
     224  
     225  #define obstack_alignment_mask(h) ((h)->alignment_mask)
     226  
     227  /* To prevent prototype warnings provide complete argument list.  */
     228  #define obstack_init(h)							      \
     229    _obstack_begin ((h), 0, 0,						      \
     230  		  (void *(*)(long))obstack_chunk_alloc,			      \
     231  		  (void (*)(void *))obstack_chunk_free)
     232  
     233  #define obstack_begin(h, size)						      \
     234    _obstack_begin ((h), (size), 0,					      \
     235  		  (void *(*)(long))obstack_chunk_alloc,			      \
     236  		  (void (*)(void *))obstack_chunk_free)
     237  
     238  #define obstack_specify_allocation(h, size, alignment, chunkfun, freefun)  \
     239    _obstack_begin ((h), (size), (alignment),				      \
     240  		  (void *(*)(long))(chunkfun),				      \
     241  		  (void (*)(void *))(freefun))
     242  
     243  #define obstack_specify_allocation_with_arg(h, size, alignment, chunkfun, freefun, arg) \
     244    _obstack_begin_1 ((h), (size), (alignment),				      \
     245  		    (void *(*)(void *, long))(chunkfun),		      \
     246  		    (void (*)(void *, void *))(freefun), (arg))
     247  
     248  #define obstack_chunkfun(h, newchunkfun) \
     249    ((h)->chunkfun = (struct _obstack_chunk *(*)(void *, long))(newchunkfun))
     250  
     251  #define obstack_freefun(h, newfreefun) \
     252    ((h)->freefun = (void (*)(void *, struct _obstack_chunk *))(newfreefun))
     253  
     254  #define obstack_1grow_fast(h, achar) (*((h)->next_free)++ = (achar))
     255  
     256  #define obstack_blank_fast(h, n) ((h)->next_free += (n))
     257  
     258  #define obstack_memory_used(h) _obstack_memory_used (h)
     259  
     260  #if defined __GNUC__
     261  # if ! (2 < __GNUC__ + (8 <= __GNUC_MINOR__))
     262  #  define __extension__
     263  # endif
     264  
     265  /* For GNU C, if not -traditional,
     266     we can define these macros to compute all args only once
     267     without using a global variable.
     268     Also, we can avoid using the 'temp' slot, to make faster code.  */
     269  
     270  # define obstack_object_size(OBSTACK)					      \
     271    __extension__								      \
     272      ({ struct obstack const *__o = (OBSTACK);				      \
     273         (unsigned) (__o->next_free - __o->object_base); })
     274  
     275  # define obstack_room(OBSTACK)						      \
     276    __extension__								      \
     277      ({ struct obstack const *__o = (OBSTACK);				      \
     278         (unsigned) (__o->chunk_limit - __o->next_free); })
     279  
     280  # define obstack_make_room(OBSTACK, length)				      \
     281    __extension__								      \
     282      ({ struct obstack *__o = (OBSTACK);					      \
     283         int __len = (length);						      \
     284         if (__o->chunk_limit - __o->next_free < __len)			      \
     285  	 _obstack_newchunk (__o, __len);				      \
     286         (void) 0; })
     287  
     288  # define obstack_empty_p(OBSTACK)					      \
     289    __extension__								      \
     290      ({ struct obstack const *__o = (OBSTACK);				      \
     291         (__o->chunk->prev == 0						      \
     292  	&& __o->next_free == __PTR_ALIGN ((char *) __o->chunk,		      \
     293  					  __o->chunk->contents,		      \
     294  					  __o->alignment_mask)); })
     295  
     296  # define obstack_grow(OBSTACK, where, length)				      \
     297    __extension__								      \
     298      ({ struct obstack *__o = (OBSTACK);					      \
     299         int __len = (length);						      \
     300         if (__o->next_free + __len > __o->chunk_limit)			      \
     301  	 _obstack_newchunk (__o, __len);				      \
     302         memcpy (__o->next_free, where, __len);				      \
     303         __o->next_free += __len;						      \
     304         (void) 0; })
     305  
     306  # define obstack_grow0(OBSTACK, where, length)				      \
     307    __extension__								      \
     308      ({ struct obstack *__o = (OBSTACK);					      \
     309         int __len = (length);						      \
     310         if (__o->next_free + __len + 1 > __o->chunk_limit)		      \
     311  	 _obstack_newchunk (__o, __len + 1);				      \
     312         memcpy (__o->next_free, where, __len);				      \
     313         __o->next_free += __len;						      \
     314         *(__o->next_free)++ = 0;						      \
     315         (void) 0; })
     316  
     317  # define obstack_1grow(OBSTACK, datum)					      \
     318    __extension__								      \
     319      ({ struct obstack *__o = (OBSTACK);					      \
     320         if (__o->next_free + 1 > __o->chunk_limit)			      \
     321  	 _obstack_newchunk (__o, 1);					      \
     322         obstack_1grow_fast (__o, datum);					      \
     323         (void) 0; })
     324  
     325  /* These assume that the obstack alignment is good enough for pointers
     326     or ints, and that the data added so far to the current object
     327     shares that much alignment.  */
     328  
     329  # define obstack_ptr_grow(OBSTACK, datum)				      \
     330    __extension__								      \
     331      ({ struct obstack *__o = (OBSTACK);					      \
     332         if (__o->next_free + sizeof (void *) > __o->chunk_limit)		      \
     333  	 _obstack_newchunk (__o, sizeof (void *));			      \
     334         obstack_ptr_grow_fast (__o, datum); })				      \
     335  
     336  # define obstack_int_grow(OBSTACK, datum)				      \
     337    __extension__								      \
     338      ({ struct obstack *__o = (OBSTACK);					      \
     339         if (__o->next_free + sizeof (int) > __o->chunk_limit)		      \
     340  	 _obstack_newchunk (__o, sizeof (int));				      \
     341         obstack_int_grow_fast (__o, datum); })
     342  
     343  # define obstack_ptr_grow_fast(OBSTACK, aptr)				      \
     344    __extension__								      \
     345      ({ struct obstack *__o1 = (OBSTACK);				      \
     346         void *__p1 = __o1->next_free;					      \
     347         *(const void **) __p1 = (aptr);					      \
     348         __o1->next_free += sizeof (const void *);			      \
     349         (void) 0; })
     350  
     351  # define obstack_int_grow_fast(OBSTACK, aint)				      \
     352    __extension__								      \
     353      ({ struct obstack *__o1 = (OBSTACK);				      \
     354         void *__p1 = __o1->next_free;					      \
     355         *(int *) __p1 = (aint);						      \
     356         __o1->next_free += sizeof (int);					      \
     357         (void) 0; })
     358  
     359  # define obstack_blank(OBSTACK, length)					      \
     360    __extension__								      \
     361      ({ struct obstack *__o = (OBSTACK);					      \
     362         int __len = (length);						      \
     363         if (__o->chunk_limit - __o->next_free < __len)			      \
     364  	 _obstack_newchunk (__o, __len);				      \
     365         obstack_blank_fast (__o, __len);					      \
     366         (void) 0; })
     367  
     368  # define obstack_alloc(OBSTACK, length)					      \
     369    __extension__								      \
     370      ({ struct obstack *__h = (OBSTACK);					      \
     371         obstack_blank (__h, (length));					      \
     372         obstack_finish (__h); })
     373  
     374  # define obstack_copy(OBSTACK, where, length)				      \
     375    __extension__								      \
     376      ({ struct obstack *__h = (OBSTACK);					      \
     377         obstack_grow (__h, (where), (length));				      \
     378         obstack_finish (__h); })
     379  
     380  # define obstack_copy0(OBSTACK, where, length)				      \
     381    __extension__								      \
     382      ({ struct obstack *__h = (OBSTACK);					      \
     383         obstack_grow0 (__h, (where), (length));				      \
     384         obstack_finish (__h); })
     385  
     386  /* The local variable is named __o1 to avoid a name conflict
     387     when obstack_blank is called.  */
     388  # define obstack_finish(OBSTACK)					      \
     389    __extension__								      \
     390      ({ struct obstack *__o1 = (OBSTACK);				      \
     391         void *__value = (void *) __o1->object_base;			      \
     392         if (__o1->next_free == __value)					      \
     393  	 __o1->maybe_empty_object = 1;					      \
     394         __o1->next_free							      \
     395  	 = __PTR_ALIGN (__o1->object_base, __o1->next_free,		      \
     396  			__o1->alignment_mask);				      \
     397         if (__o1->next_free - (char *) __o1->chunk			      \
     398  	   > __o1->chunk_limit - (char *) __o1->chunk)			      \
     399  	 __o1->next_free = __o1->chunk_limit;				      \
     400         __o1->object_base = __o1->next_free;				      \
     401         __value; })
     402  
     403  # define obstack_free(OBSTACK, OBJ)					      \
     404    __extension__								      \
     405      ({ struct obstack *__o = (OBSTACK);					      \
     406         void *__obj = (OBJ);						      \
     407         if (__obj > (void *) __o->chunk && __obj < (void *) __o->chunk_limit)  \
     408  	 __o->next_free = __o->object_base = (char *) __obj;		      \
     409         else (__obstack_free) (__o, __obj); })
     410  
     411  #else /* not __GNUC__ */
     412  
     413  # define obstack_object_size(h) \
     414    (unsigned) ((h)->next_free - (h)->object_base)
     415  
     416  # define obstack_room(h)						      \
     417    (unsigned) ((h)->chunk_limit - (h)->next_free)
     418  
     419  # define obstack_empty_p(h) \
     420    ((h)->chunk->prev == 0						      \
     421     && (h)->next_free == __PTR_ALIGN ((char *) (h)->chunk,		      \
     422  				     (h)->chunk->contents,		      \
     423  				     (h)->alignment_mask))
     424  
     425  /* Note that the call to _obstack_newchunk is enclosed in (..., 0)
     426     so that we can avoid having void expressions
     427     in the arms of the conditional expression.
     428     Casting the third operand to void was tried before,
     429     but some compilers won't accept it.  */
     430  
     431  # define obstack_make_room(h, length)					      \
     432    ((h)->temp.tempint = (length),					      \
     433     (((h)->next_free + (h)->temp.tempint > (h)->chunk_limit)		      \
     434     ? (_obstack_newchunk ((h), (h)->temp.tempint), 0) : 0))
     435  
     436  # define obstack_grow(h, where, length)					      \
     437    ((h)->temp.tempint = (length),					      \
     438     (((h)->next_free + (h)->temp.tempint > (h)->chunk_limit)		      \
     439     ? (_obstack_newchunk ((h), (h)->temp.tempint), 0) : 0),		      \
     440     memcpy ((h)->next_free, where, (h)->temp.tempint),			      \
     441     (h)->next_free += (h)->temp.tempint)
     442  
     443  # define obstack_grow0(h, where, length)				      \
     444    ((h)->temp.tempint = (length),					      \
     445     (((h)->next_free + (h)->temp.tempint + 1 > (h)->chunk_limit)		      \
     446     ? (_obstack_newchunk ((h), (h)->temp.tempint + 1), 0) : 0),		      \
     447     memcpy ((h)->next_free, where, (h)->temp.tempint),			      \
     448     (h)->next_free += (h)->temp.tempint,					      \
     449     *((h)->next_free)++ = 0)
     450  
     451  # define obstack_1grow(h, datum)					      \
     452    ((((h)->next_free + 1 > (h)->chunk_limit)				      \
     453      ? (_obstack_newchunk ((h), 1), 0) : 0),				      \
     454     obstack_1grow_fast (h, datum))
     455  
     456  # define obstack_ptr_grow(h, datum)					      \
     457    ((((h)->next_free + sizeof (char *) > (h)->chunk_limit)		      \
     458      ? (_obstack_newchunk ((h), sizeof (char *)), 0) : 0),		      \
     459     obstack_ptr_grow_fast (h, datum))
     460  
     461  # define obstack_int_grow(h, datum)					      \
     462    ((((h)->next_free + sizeof (int) > (h)->chunk_limit)			      \
     463      ? (_obstack_newchunk ((h), sizeof (int)), 0) : 0),			      \
     464     obstack_int_grow_fast (h, datum))
     465  
     466  # define obstack_ptr_grow_fast(h, aptr)					      \
     467    (((const void **) ((h)->next_free += sizeof (void *)))[-1] = (aptr))
     468  
     469  # define obstack_int_grow_fast(h, aint)					      \
     470    (((int *) ((h)->next_free += sizeof (int)))[-1] = (aint))
     471  
     472  # define obstack_blank(h, length)					      \
     473    ((h)->temp.tempint = (length),					      \
     474     (((h)->chunk_limit - (h)->next_free < (h)->temp.tempint)		      \
     475     ? (_obstack_newchunk ((h), (h)->temp.tempint), 0) : 0),		      \
     476     obstack_blank_fast (h, (h)->temp.tempint))
     477  
     478  # define obstack_alloc(h, length)					      \
     479    (obstack_blank ((h), (length)), obstack_finish ((h)))
     480  
     481  # define obstack_copy(h, where, length)					      \
     482    (obstack_grow ((h), (where), (length)), obstack_finish ((h)))
     483  
     484  # define obstack_copy0(h, where, length)				      \
     485    (obstack_grow0 ((h), (where), (length)), obstack_finish ((h)))
     486  
     487  # define obstack_finish(h)						      \
     488    (((h)->next_free == (h)->object_base					      \
     489      ? (((h)->maybe_empty_object = 1), 0)				      \
     490      : 0),								      \
     491     (h)->temp.tempptr = (h)->object_base,				      \
     492     (h)->next_free							      \
     493       = __PTR_ALIGN ((h)->object_base, (h)->next_free,			      \
     494  		    (h)->alignment_mask),				      \
     495     (((h)->next_free - (char *) (h)->chunk				      \
     496       > (h)->chunk_limit - (char *) (h)->chunk)				      \
     497     ? ((h)->next_free = (h)->chunk_limit) : 0),				      \
     498     (h)->object_base = (h)->next_free,					      \
     499     (h)->temp.tempptr)
     500  
     501  # define obstack_free(h, obj)						      \
     502    ((h)->temp.tempint = (char *) (obj) - (char *) (h)->chunk,		      \
     503     ((((h)->temp.tempint > 0						      \
     504        && (h)->temp.tempint < (h)->chunk_limit - (char *) (h)->chunk))	      \
     505      ? (void) ((h)->next_free = (h)->object_base				      \
     506  	      = (h)->temp.tempint + (char *) (h)->chunk)		      \
     507      : (__obstack_free) (h, (h)->temp.tempint + (char *) (h)->chunk)))
     508  
     509  #endif /* not __GNUC__ */
     510  
     511  #ifdef __cplusplus
     512  }       /* C++ */
     513  #endif
     514  
     515  #endif /* obstack.h */