(linenum→info "unix/slp.c:2238")

glibc/2.7/malloc/obstack.h

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