Annotation of gcc/obstack.h, revision 1.1.1.1

1.1       root        1: /* obstack.h - object stack macros
                      2:    Copyright (C) 1988 Free Software Foundation, Inc.
                      3: 
                      4: This program is free software; you can redistribute it and/or modify it
                      5: under the terms of the GNU General Public License as published by the
                      6: Free Software Foundation; either version 2, or (at your option) any
                      7: later version.
                      8: 
                      9: This program is distributed in the hope that it will be useful,
                     10: but WITHOUT ANY WARRANTY; without even the implied warranty of
                     11: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
                     12: GNU General Public License for more details.
                     13: 
                     14: You should have received a copy of the GNU General Public License
                     15: along with this program; if not, write to the Free Software
                     16: Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
                     17: 
                     18: /* Summary:
                     19: 
                     20: All the apparent functions defined here are macros. The idea
                     21: is that you would use these pre-tested macros to solve a
                     22: very specific set of problems, and they would run fast.
                     23: Caution: no side-effects in arguments please!! They may be
                     24: evaluated MANY times!!
                     25: 
                     26: These macros operate a stack of objects.  Each object starts life
                     27: small, and may grow to maturity.  (Consider building a word syllable
                     28: by syllable.)  An object can move while it is growing.  Once it has
                     29: been "finished" it never changes address again.  So the "top of the
                     30: stack" is typically an immature growing object, while the rest of the
                     31: stack is of mature, fixed size and fixed address objects.
                     32: 
                     33: These routines grab large chunks of memory, using a function you
                     34: supply, called `obstack_chunk_alloc'.  On occasion, they free chunks,
                     35: by calling `obstack_chunk_free'.  You must define them and declare
                     36: them before using any obstack macros.
                     37: 
                     38: Each independent stack is represented by a `struct obstack'.
                     39: Each of the obstack macros expects a pointer to such a structure
                     40: as the first argument.
                     41: 
                     42: One motivation for this package is the problem of growing char strings
                     43: in symbol tables.  Unless you are "fascist pig with a read-only mind"
                     44: [Gosper's immortal quote from HAKMEM item 154, out of context] you
                     45: would not like to put any arbitrary upper limit on the length of your
                     46: symbols.
                     47: 
                     48: In practice this often means you will build many short symbols and a
                     49: few long symbols.  At the time you are reading a symbol you don't know
                     50: how long it is.  One traditional method is to read a symbol into a
                     51: buffer, realloc()ating the buffer every time you try to read a symbol
                     52: that is longer than the buffer.  This is beaut, but you still will
                     53: want to copy the symbol from the buffer to a more permanent
                     54: symbol-table entry say about half the time.
                     55: 
                     56: With obstacks, you can work differently.  Use one obstack for all symbol
                     57: names.  As you read a symbol, grow the name in the obstack gradually.
                     58: When the name is complete, finalize it.  Then, if the symbol exists already,
                     59: free the newly read name.
                     60: 
                     61: The way we do this is to take a large chunk, allocating memory from
                     62: low addresses.  When you want to build a symbol in the chunk you just
                     63: add chars above the current "high water mark" in the chunk.  When you
                     64: have finished adding chars, because you got to the end of the symbol,
                     65: you know how long the chars are, and you can create a new object.
                     66: Mostly the chars will not burst over the highest address of the chunk,
                     67: because you would typically expect a chunk to be (say) 100 times as
                     68: long as an average object.
                     69: 
                     70: In case that isn't clear, when we have enough chars to make up
                     71: the object, THEY ARE ALREADY CONTIGUOUS IN THE CHUNK (guaranteed)
                     72: so we just point to it where it lies.  No moving of chars is
                     73: needed and this is the second win: potentially long strings need
                     74: never be explicitly shuffled. Once an object is formed, it does not
                     75: change its address during its lifetime.
                     76: 
                     77: When the chars burst over a chunk boundary, we allocate a larger
                     78: chunk, and then copy the partly formed object from the end of the old
                     79: chunk to the beginning of the new larger chunk.  We then carry on
                     80: accreting characters to the end of the object as we normally would.
                     81: 
                     82: A special macro is provided to add a single char at a time to a
                     83: growing object.  This allows the use of register variables, which
                     84: break the ordinary 'growth' macro.
                     85: 
                     86: Summary:
                     87:        We allocate large chunks.
                     88:        We carve out one object at a time from the current chunk.
                     89:        Once carved, an object never moves.
                     90:        We are free to append data of any size to the currently
                     91:          growing object.
                     92:        Exactly one object is growing in an obstack at any one time.
                     93:        You can run one obstack per control block.
                     94:        You may have as many control blocks as you dare.
                     95:        Because of the way we do it, you can `unwind' a obstack
                     96:          back to a previous state. (You may remove objects much
                     97:          as you would with a stack.)
                     98: */
                     99: 
                    100: 
                    101: /* Don't do the contents of this file more than once.  */
                    102: 
                    103: #ifndef __OBSTACKS__
                    104: #define __OBSTACKS__
                    105: 
                    106: /* We use subtraction of (char *)0 instead of casting to int
                    107:    because on word-addressable machines a simple cast to int
                    108:    may ignore the byte-within-word field of the pointer.  */
                    109: 
                    110: #ifndef __PTR_TO_INT
                    111: #define __PTR_TO_INT(P) ((P) - (char *)0)
                    112: #endif
                    113: 
                    114: #ifndef __INT_TO_PTR
                    115: #define __INT_TO_PTR(P) ((P) + (char *)0)
                    116: #endif
                    117: 
                    118: struct _obstack_chunk          /* Lives at front of each chunk. */
                    119: {
                    120:   char  *limit;                        /* 1 past end of this chunk */
                    121:   struct _obstack_chunk *prev; /* address of prior chunk or NULL */
                    122:   char contents[4];            /* objects begin here */
                    123: };
                    124: 
                    125: struct obstack         /* control current object in current chunk */
                    126: {
                    127:   long chunk_size;             /* preferred size to allocate chunks in */
                    128:   struct _obstack_chunk* chunk;        /* address of current struct obstack_chunk */
                    129:   char *object_base;           /* address of object we are building */
                    130:   char *next_free;             /* where to add next char to current object */
                    131:   char *chunk_limit;           /* address of char after current chunk */
                    132:   int  temp;                   /* Temporary for some macros.  */
                    133:   int   alignment_mask;                /* Mask of alignment for each object. */
                    134:   struct _obstack_chunk *(*chunkfun) (); /* User's fcn to allocate a chunk.  */
                    135:   void (*freefun) ();          /* User's function to free a chunk.  */
                    136:   /* Nonzero means there is a possibility the current chunk contains
                    137:      a zero-length object.  This prevents freeing the chunk
                    138:      if we allocate a bigger chunk to replace it.  */
                    139:   char  maybe_empty_object;
                    140: };
                    141: 
                    142: /* Declare the external functions we use; they are in obstack.c.  */
                    143: 
                    144: #ifdef __STDC__
                    145: extern void _obstack_newchunk (struct obstack *, int);
                    146: extern void _obstack_free (struct obstack *, void *);
                    147: extern void _obstack_begin (struct obstack *, int, int,
                    148:                            void *(*) (), void (*) ());
                    149: #else
                    150: extern void _obstack_newchunk ();
                    151: extern void _obstack_free ();
                    152: extern void _obstack_begin ();
                    153: #endif
                    154: 
                    155: #ifdef __STDC__
                    156: 
                    157: /* Do the function-declarations after the structs
                    158:    but before defining the macros.  */
                    159: 
                    160: void obstack_init (struct obstack *obstack);
                    161: 
                    162: void * obstack_alloc (struct obstack *obstack, int size);
                    163: 
                    164: void * obstack_copy (struct obstack *obstack, void *address, int size);
                    165: void * obstack_copy0 (struct obstack *obstack, void *address, int size);
                    166: 
                    167: void obstack_free (struct obstack *obstack, void *block);
                    168: 
                    169: void obstack_blank (struct obstack *obstack, int size);
                    170: 
                    171: void obstack_grow (struct obstack *obstack, void *data, int size);
                    172: void obstack_grow0 (struct obstack *obstack, void *data, int size);
                    173: 
                    174: void obstack_1grow (struct obstack *obstack, int data_char);
                    175: void obstack_ptr_grow (struct obstack *obstack, void *data);
                    176: void obstack_int_grow (struct obstack *obstack, int data);
                    177: 
                    178: void * obstack_finish (struct obstack *obstack);
                    179: 
                    180: int obstack_object_size (struct obstack *obstack);
                    181: 
                    182: int obstack_room (struct obstack *obstack);
                    183: void obstack_1grow_fast (struct obstack *obstack, int data_char);
                    184: void obstack_ptr_grow_fast (struct obstack *obstack, void *data);
                    185: void obstack_int_grow_fast (struct obstack *obstack, int data);
                    186: void obstack_blank_fast (struct obstack *obstack, int size);
                    187: 
                    188: void * obstack_base (struct obstack *obstack);
                    189: void * obstack_next_free (struct obstack *obstack);
                    190: int obstack_alignment_mask (struct obstack *obstack);
                    191: int obstack_chunk_size (struct obstack *obstack);
                    192: 
                    193: #endif /* __STDC__ */
                    194: 
                    195: /* Non-ANSI C cannot really support alternative functions for these macros,
                    196:    so we do not declare them.  */
                    197: 
                    198: /* Pointer to beginning of object being allocated or to be allocated next.
                    199:    Note that this might not be the final address of the object
                    200:    because a new chunk might be needed to hold the final size.  */
                    201: 
                    202: #define obstack_base(h) ((h)->object_base)
                    203: 
                    204: /* Size for allocating ordinary chunks.  */
                    205: 
                    206: #define obstack_chunk_size(h) ((h)->chunk_size)
                    207: 
                    208: /* Pointer to next byte not yet allocated in current chunk.  */
                    209: 
                    210: #define obstack_next_free(h)   ((h)->next_free)
                    211: 
                    212: /* Mask specifying low bits that should be clear in address of an object.  */
                    213: 
                    214: #define obstack_alignment_mask(h) ((h)->alignment_mask)
                    215: 
                    216: #define obstack_init(h) \
                    217:   _obstack_begin ((h), 0, 0, \
                    218:                  (void *(*) ()) obstack_chunk_alloc, obstack_chunk_free)
                    219: 
                    220: #define obstack_begin(h, size) \
                    221:   _obstack_begin ((h), (size), 0, \
                    222:                  (void *(*) ()) obstack_chunk_alloc, obstack_chunk_free)
                    223: 
                    224: #define obstack_1grow_fast(h,achar) (*((h)->next_free)++ = achar)
                    225: 
                    226: #define obstack_blank_fast(h,n) ((h)->next_free += (n))
                    227: 
                    228: #if defined (__GNUC__) && defined (__STDC__)
                    229: #if __GNUC__ < 2
                    230: #define __extension__
                    231: #endif
                    232: 
                    233: /* For GNU C, if not -traditional,
                    234:    we can define these macros to compute all args only once
                    235:    without using a global variable.
                    236:    Also, we can avoid using the `temp' slot, to make faster code.  */
                    237: 
                    238: #define obstack_object_size(OBSTACK)                                   \
                    239:   __extension__                                                                \
                    240:   ({ struct obstack *__o = (OBSTACK);                                  \
                    241:      (unsigned) (__o->next_free - __o->object_base); })
                    242: 
                    243: #define obstack_room(OBSTACK)                                          \
                    244:   __extension__                                                                \
                    245:   ({ struct obstack *__o = (OBSTACK);                                  \
                    246:      (unsigned) (__o->chunk_limit - __o->next_free); })
                    247: 
                    248: /* Note that the call to _obstack_newchunk is enclosed in (..., 0)
                    249:    so that we can avoid having void expressions
                    250:    in the arms of the conditional expression.
                    251:    Casting the third operand to void was tried before,
                    252:    but some compilers won't accept it.  */
                    253: #define obstack_grow(OBSTACK,where,length)                             \
                    254: __extension__                                                          \
                    255: ({ struct obstack *__o = (OBSTACK);                                    \
                    256:    int __len = (length);                                               \
                    257:    ((__o->next_free + __len > __o->chunk_limit)                                \
                    258:     ? (_obstack_newchunk (__o, __len), 0) : 0);                                \
                    259:    bcopy (where, __o->next_free, __len);                               \
                    260:    __o->next_free += __len;                                            \
                    261:    (void) 0; })
                    262: 
                    263: #define obstack_grow0(OBSTACK,where,length)                            \
                    264: __extension__                                                          \
                    265: ({ struct obstack *__o = (OBSTACK);                                    \
                    266:    int __len = (length);                                               \
                    267:    ((__o->next_free + __len + 1 > __o->chunk_limit)                    \
                    268:     ? (_obstack_newchunk (__o, __len + 1), 0) : 0),                    \
                    269:    bcopy (where, __o->next_free, __len),                               \
                    270:    __o->next_free += __len,                                            \
                    271:    *(__o->next_free)++ = 0;                                            \
                    272:    (void) 0; })
                    273: 
                    274: #define obstack_1grow(OBSTACK,datum)                                   \
                    275: __extension__                                                          \
                    276: ({ struct obstack *__o = (OBSTACK);                                    \
                    277:    ((__o->next_free + 1 > __o->chunk_limit)                            \
                    278:     ? (_obstack_newchunk (__o, 1), 0) : 0),                            \
                    279:    *(__o->next_free)++ = (datum);                                      \
                    280:    (void) 0; })
                    281: 
                    282: /* These assume that the obstack alignment is good enough for pointers or ints,
                    283:    and that the data added so far to the current object
                    284:    shares that much alignment.  */
                    285:    
                    286: #define obstack_ptr_grow(OBSTACK,datum)                                        \
                    287: __extension__                                                          \
                    288: ({ struct obstack *__o = (OBSTACK);                                    \
                    289:    ((__o->next_free + sizeof (void *) > __o->chunk_limit)              \
                    290:     ? (_obstack_newchunk (__o, sizeof (void *)), 0) : 0),              \
                    291:    *((void **)__o->next_free)++ = ((void *)datum);                     \
                    292:    (void) 0; })
                    293: 
                    294: #define obstack_int_grow(OBSTACK,datum)                                        \
                    295: __extension__                                                          \
                    296: ({ struct obstack *__o = (OBSTACK);                                    \
                    297:    ((__o->next_free + sizeof (int) > __o->chunk_limit)                 \
                    298:     ? (_obstack_newchunk (__o, sizeof (int)), 0) : 0),                 \
                    299:    *((int *)__o->next_free)++ = ((int)datum);                          \
                    300:    (void) 0; })
                    301: 
                    302: #define obstack_ptr_grow_fast(h,aptr) (*((void **)(h)->next_free)++ = (void *)aptr)
                    303: #define obstack_int_grow_fast(h,aint) (*((int *)(h)->next_free)++ = (int)aint)
                    304: 
                    305: #define obstack_blank(OBSTACK,length)                                  \
                    306: __extension__                                                          \
                    307: ({ struct obstack *__o = (OBSTACK);                                    \
                    308:    int __len = (length);                                               \
                    309:    ((__o->chunk_limit - __o->next_free < __len)                                \
                    310:     ? (_obstack_newchunk (__o, __len), 0) : 0);                                \
                    311:    __o->next_free += __len;                                            \
                    312:    (void) 0; })
                    313: 
                    314: #define obstack_alloc(OBSTACK,length)                                  \
                    315: __extension__                                                          \
                    316: ({ struct obstack *__h = (OBSTACK);                                    \
                    317:    obstack_blank (__h, (length));                                      \
                    318:    obstack_finish (__h); })
                    319: 
                    320: #define obstack_copy(OBSTACK,where,length)                             \
                    321: __extension__                                                          \
                    322: ({ struct obstack *__h = (OBSTACK);                                    \
                    323:    obstack_grow (__h, (where), (length));                              \
                    324:    obstack_finish (__h); })
                    325: 
                    326: #define obstack_copy0(OBSTACK,where,length)                            \
                    327: __extension__                                                          \
                    328: ({ struct obstack *__h = (OBSTACK);                                    \
                    329:    obstack_grow0 (__h, (where), (length));                             \
                    330:    obstack_finish (__h); })
                    331: 
                    332: /* The local variable is named __o1 to avoid a name conflict
                    333:    when obstack_blank is called.  */
                    334: #define obstack_finish(OBSTACK)                                        \
                    335: __extension__                                                          \
                    336: ({ struct obstack *__o1 = (OBSTACK);                                   \
                    337:    void *value = (void *) __o1->object_base;                           \
                    338:    if (__o1->next_free == value)                                       \
                    339:      __o1->maybe_empty_object = 1;                                     \
                    340:    __o1->next_free                                                     \
                    341:      = __INT_TO_PTR ((__PTR_TO_INT (__o1->next_free)+__o1->alignment_mask)\
                    342:                     & ~ (__o1->alignment_mask));                       \
                    343:    ((__o1->next_free - (char *)__o1->chunk                             \
                    344:      > __o1->chunk_limit - (char *)__o1->chunk)                                \
                    345:     ? (__o1->next_free = __o1->chunk_limit) : 0);                      \
                    346:    __o1->object_base = __o1->next_free;                                        \
                    347:    value; })
                    348: 
                    349: #define obstack_free(OBSTACK, OBJ)                                     \
                    350: __extension__                                                          \
                    351: ({ struct obstack *__o = (OBSTACK);                                    \
                    352:    void *__obj = (OBJ);                                                        \
                    353:    if (__obj > (void *)__o->chunk && __obj < (void *)__o->chunk_limit)  \
                    354:      __o->next_free = __o->object_base = __obj;                                \
                    355:    else (obstack_free) (__o, __obj); })
                    356: 
                    357: #else /* not __GNUC__ or not __STDC__ */
                    358: 
                    359: #define obstack_object_size(h) \
                    360:  (unsigned) ((h)->next_free - (h)->object_base)
                    361: 
                    362: #define obstack_room(h)                \
                    363:  (unsigned) ((h)->chunk_limit - (h)->next_free)
                    364: 
                    365: #define obstack_grow(h,where,length)                                   \
                    366: ( (h)->temp = (length),                                                        \
                    367:   (((h)->next_free + (h)->temp > (h)->chunk_limit)                     \
                    368:    ? (_obstack_newchunk ((h), (h)->temp), 0) : 0),                     \
                    369:   bcopy (where, (h)->next_free, (h)->temp),                            \
                    370:   (h)->next_free += (h)->temp)
                    371: 
                    372: #define obstack_grow0(h,where,length)                                  \
                    373: ( (h)->temp = (length),                                                        \
                    374:   (((h)->next_free + (h)->temp + 1 > (h)->chunk_limit)                 \
                    375:    ? (_obstack_newchunk ((h), (h)->temp + 1), 0) : 0),                 \
                    376:   bcopy (where, (h)->next_free, (h)->temp),                            \
                    377:   (h)->next_free += (h)->temp,                                         \
                    378:   *((h)->next_free)++ = 0)
                    379: 
                    380: #define obstack_1grow(h,datum)                                         \
                    381: ( (((h)->next_free + 1 > (h)->chunk_limit)                             \
                    382:    ? (_obstack_newchunk ((h), 1), 0) : 0),                             \
                    383:   *((h)->next_free)++ = (datum))
                    384: 
                    385: #define obstack_ptr_grow(h,datum)                                      \
                    386: ( (((h)->next_free + sizeof (char *) > (h)->chunk_limit)               \
                    387:    ? (_obstack_newchunk ((h), sizeof (char *)), 0) : 0),               \
                    388:   *((char **)(((h)->next_free+=sizeof(char *))-sizeof(char *))) = ((char *)datum))
                    389: 
                    390: #define obstack_int_grow(h,datum)                                      \
                    391: ( (((h)->next_free + sizeof (int) > (h)->chunk_limit)                  \
                    392:    ? (_obstack_newchunk ((h), sizeof (int)), 0) : 0),                  \
                    393:   *((int *)(((h)->next_free+=sizeof(int))-sizeof(int))) = ((int)datum))
                    394: 
                    395: #define obstack_ptr_grow_fast(h,aptr) (*((char **)(h)->next_free)++ = (char *)aptr)
                    396: #define obstack_int_grow_fast(h,aint) (*((int *)(h)->next_free)++ = (int)aint)
                    397: 
                    398: #define obstack_blank(h,length)                                                \
                    399: ( (h)->temp = (length),                                                        \
                    400:   (((h)->chunk_limit - (h)->next_free < (h)->temp)                     \
                    401:    ? (_obstack_newchunk ((h), (h)->temp), 0) : 0),                     \
                    402:   (h)->next_free += (h)->temp)
                    403: 
                    404: #define obstack_alloc(h,length)                                                \
                    405:  (obstack_blank ((h), (length)), obstack_finish ((h)))
                    406: 
                    407: #define obstack_copy(h,where,length)                                   \
                    408:  (obstack_grow ((h), (where), (length)), obstack_finish ((h)))
                    409: 
                    410: #define obstack_copy0(h,where,length)                                  \
                    411:  (obstack_grow0 ((h), (where), (length)), obstack_finish ((h)))
                    412: 
                    413: #define obstack_finish(h)                                              \
                    414: ( ((h)->next_free == (h)->object_base                                  \
                    415:    ? (((h)->maybe_empty_object = 1), 0)                                        \
                    416:    : 0),                                                               \
                    417:   (h)->temp = __PTR_TO_INT ((h)->object_base),                         \
                    418:   (h)->next_free                                                       \
                    419:     = __INT_TO_PTR ((__PTR_TO_INT ((h)->next_free)+(h)->alignment_mask)        \
                    420:                    & ~ ((h)->alignment_mask)),                         \
                    421:   (((h)->next_free - (char *)(h)->chunk                                        \
                    422:     > (h)->chunk_limit - (char *)(h)->chunk)                           \
                    423:    ? ((h)->next_free = (h)->chunk_limit) : 0),                         \
                    424:   (h)->object_base = (h)->next_free,                                   \
                    425:   __INT_TO_PTR ((h)->temp))
                    426: 
                    427: #ifdef __STDC__
                    428: #define obstack_free(h,obj)                                            \
                    429: ( (h)->temp = (char *)(obj) - (char *) (h)->chunk,                     \
                    430:   (((h)->temp > 0 && (h)->temp < (h)->chunk_limit - (char *) (h)->chunk)\
                    431:    ? (int) ((h)->next_free = (h)->object_base                          \
                    432:            = (h)->temp + (char *) (h)->chunk)                          \
                    433:    : (((obstack_free) ((h), (h)->temp + (char *) (h)->chunk), 0), 0)))
                    434: #else
                    435: #define obstack_free(h,obj)                                            \
                    436: ( (h)->temp = (char *)(obj) - (char *) (h)->chunk,                     \
                    437:   (((h)->temp > 0 && (h)->temp < (h)->chunk_limit - (char *) (h)->chunk)\
                    438:    ? (int) ((h)->next_free = (h)->object_base                          \
                    439:            = (h)->temp + (char *) (h)->chunk)                          \
                    440:    : (_obstack_free ((h), (h)->temp + (char *) (h)->chunk), 0)))
                    441: #endif
                    442: 
                    443: #endif /* not __GNUC__ or not __STDC__ */
                    444: 
                    445: #endif /* not __OBSTACKS__ */

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.