Annotation of GNUtools/cctools/as/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 1, 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: #define obstack_chunk_alloc    xmalloc
                    107: #define obstack_chunk_free     xfree
                    108: 
                    109: /* We use subtraction of (char *)0 instead of casting to int
                    110:    because on word-addressable machines a simple cast to int
                    111:    may ignore the byte-within-word field of the pointer.  */
                    112: 
                    113: #ifndef __PTR_TO_INT
                    114: #define __PTR_TO_INT(P) ((P) - (char *)0)
                    115: #endif
                    116: 
                    117: #ifndef __INT_TO_PTR
                    118: #define __INT_TO_PTR(P) ((P) + (char *)0)
                    119: #endif
                    120: 
                    121: struct _obstack_chunk          /* Lives at front of each chunk. */
                    122: {
                    123:   char  *limit;                        /* 1 past end of this chunk */
                    124:   struct _obstack_chunk *prev; /* address of prior chunk or NULL */
                    125:   char contents[4];            /* objects begin here */
                    126: };
                    127: 
                    128: struct obstack         /* control current object in current chunk */
                    129: {
                    130:   long chunk_size;             /* preferred size to allocate chunks in */
                    131:   struct _obstack_chunk* chunk;        /* address of current struct obstack_chunk */
                    132:   char *object_base;           /* address of object we are building */
                    133:   char *next_free;             /* where to add next char to current object */
                    134:   char *chunk_limit;           /* address of char after current chunk */
                    135:   int  temp;                   /* Temporary for some macros.  */
                    136:   int   alignment_mask;                /* Mask of alignment for each object. */
                    137:   struct _obstack_chunk *(*chunkfun) (); /* User's fcn to allocate a chunk.  */
                    138:   void (*freefun) ();          /* User's function to free a chunk.  */
                    139: };
                    140: 
                    141: #ifdef __STDC__
                    142: 
                    143: /* Do the function-declarations after the structs
                    144:    but before defining the macros.  */
                    145: 
                    146: void obstack_init (struct obstack *obstack);
                    147: 
                    148: void * obstack_alloc (struct obstack *obstack, int size);
                    149: 
                    150: void * obstack_copy (struct obstack *obstack, void *address, int size);
                    151: void * obstack_copy0 (struct obstack *obstack, void *address, int size);
                    152: 
                    153: void obstack_free (struct obstack *obstack, void *block);
                    154: 
                    155: void obstack_blank (struct obstack *obstack, int size);
                    156: 
                    157: void obstack_grow (struct obstack *obstack, void *data, int size);
                    158: void obstack_grow0 (struct obstack *obstack, void *data, int size);
                    159: 
                    160: void obstack_1grow (struct obstack *obstack, int data_char);
                    161: void obstack_ptr_grow (struct obstack *obstack, void *data);
                    162: void obstack_int_grow (struct obstack *obstack, int data);
                    163: 
                    164: void * obstack_finish (struct obstack *obstack);
                    165: 
                    166: int obstack_object_size (struct obstack *obstack);
                    167: 
                    168: int obstack_room (struct obstack *obstack);
                    169: void obstack_1grow_fast (struct obstack *obstack, int data_char);
                    170: void obstack_ptr_grow_fast (struct obstack *obstack, void *data);
                    171: void obstack_int_grow_fast (struct obstack *obstack, int data);
                    172: void obstack_blank_fast (struct obstack *obstack, int size);
                    173: 
                    174: void * obstack_base (struct obstack *obstack);
                    175: void * obstack_next_free (struct obstack *obstack);
                    176: int obstack_alignment_mask (struct obstack *obstack);
                    177: int obstack_chunk_size (struct obstack *obstack);
                    178: 
                    179: void _obstack_begin (struct obstack *h, int size, int alignment,
                    180:                     void * (*chunkfun)(long n), void (*freefun)());
                    181: void _obstack_newchunk (struct obstack *h, int length);
                    182: #endif /* __STDC__ */
                    183: 
                    184: /* Non-ANSI C cannot really support alternative functions for these macros,
                    185:    so we do not declare them.  */
                    186: 
                    187: /* Pointer to beginning of object being allocated or to be allocated next.
                    188:    Note that this might not be the final address of the object
                    189:    because a new chunk might be needed to hold the final size.  */
                    190: 
                    191: #define obstack_base(h) ((h)->object_base)
                    192: 
                    193: /* Size for allocating ordinary chunks.  */
                    194: 
                    195: #define obstack_chunk_size(h) ((h)->chunk_size)
                    196: 
                    197: /* Pointer to next byte not yet allocated in current chunk.  */
                    198: 
                    199: #define obstack_next_free(h)   ((h)->next_free)
                    200: 
                    201: /* Mask specifying low bits that should be clear in address of an object.  */
                    202: 
                    203: #define obstack_alignment_mask(h) ((h)->alignment_mask)
                    204: 
                    205: #define obstack_init(h) \
                    206:   _obstack_begin ((h), 0, 0, obstack_chunk_alloc, obstack_chunk_free)
                    207: 
                    208: #define obstack_begin(h, size) \
                    209:   _obstack_begin ((h), (size), 0, obstack_chunk_alloc, obstack_chunk_free)
                    210: 
                    211: #define obstack_1grow_fast(h,achar) (*((h)->next_free)++ = achar)
                    212: 
                    213: #define obstack_blank_fast(h,n) ((h)->next_free += (n))
                    214: 
                    215: #if defined (__GNUC__) && defined (__STDC__)
                    216: 
                    217: /* For GNU C, if not -traditional,
                    218:    we can define these macros to compute all args only once
                    219:    without using a global variable.
                    220:    Also, we can avoid using the `temp' slot, to make faster code.  */
                    221: 
                    222: #define obstack_object_size(OBSTACK)                                   \
                    223:   ({ struct obstack *__o = (OBSTACK);                                  \
                    224:      (unsigned) (__o->next_free - __o->object_base); })
                    225: 
                    226: #define obstack_room(OBSTACK)                                          \
                    227:   ({ struct obstack *__o = (OBSTACK);                                  \
                    228:      (unsigned) (__o->chunk_limit - __o->next_free); })
                    229: 
                    230: #define obstack_grow(OBSTACK,where,length)                             \
                    231: ({ struct obstack *__o = (OBSTACK);                                    \
                    232:    int __len = (length);                                               \
                    233:    ((__o->next_free + __len > __o->chunk_limit)                                \
                    234:     ? _obstack_newchunk (__o, __len) : 0);                             \
                    235:    bcopy (where, __o->next_free, __len);                               \
                    236:    __o->next_free += __len;                                            \
                    237:    (void) 0; })
                    238: 
                    239: #define obstack_grow0(OBSTACK,where,length)                            \
                    240: ({ struct obstack *__o = (OBSTACK);                                    \
                    241:    int __len = (length);                                               \
                    242:    ((__o->next_free + __len + 1 > __o->chunk_limit)                    \
                    243:     ? _obstack_newchunk (__o, __len + 1) : 0),                         \
                    244:    bcopy (where, __o->next_free, __len),                               \
                    245:    __o->next_free += __len,                                            \
                    246:    *(__o->next_free)++ = 0;                                            \
                    247:    (void) 0; })
                    248: 
                    249: #define obstack_1grow(OBSTACK,datum)                                   \
                    250: ({ struct obstack *__o = (OBSTACK);                                    \
                    251:    ((__o->next_free + 1 > __o->chunk_limit)                            \
                    252:     ? _obstack_newchunk (__o, 1) : 0),                                 \
                    253:    *(__o->next_free)++ = (datum);                                      \
                    254:    (void) 0; })
                    255: 
                    256: /* These assume that the obstack alignment is good enough for pointers or ints,
                    257:    and that the data added so far to the current object
                    258:    shares that much alignment.  */
                    259:    
                    260: #define obstack_ptr_grow(OBSTACK,datum)                                        \
                    261: ({ struct obstack *__o = (OBSTACK);                                    \
                    262:    ((__o->next_free + sizeof (void *) > __o->chunk_limit)              \
                    263:     ? _obstack_newchunk (__o, sizeof (void *)) : 0),                   \
                    264:    *((void **)__o->next_free)++ = ((void *)datum);                     \
                    265:    (void) 0; })
                    266: 
                    267: #define obstack_int_grow(OBSTACK,datum)                                        \
                    268: ({ struct obstack *__o = (OBSTACK);                                    \
                    269:    ((__o->next_free + sizeof (int) > __o->chunk_limit)                 \
                    270:     ? _obstack_newchunk (__o, sizeof (int)) : 0),                      \
                    271:    *((int *)__o->next_free)++ = ((int)datum);                          \
                    272:    (void) 0; })
                    273: 
                    274: #define obstack_ptr_grow_fast(h,aptr) (*((void **)(h)->next_free)++ = (void *)aptr)
                    275: #define obstack_int_grow_fast(h,aint) (*((int *)(h)->next_free)++ = (int)aint)
                    276: 
                    277: #define obstack_blank(OBSTACK,length)                                  \
                    278: ({ struct obstack *__o = (OBSTACK);                                    \
                    279:    int __len = (length);                                               \
                    280:    ((__o->next_free + __len > __o->chunk_limit)                                \
                    281:     ? _obstack_newchunk (__o, __len) : 0);                             \
                    282:    __o->next_free += __len;                                            \
                    283:    (void) 0; })
                    284: 
                    285: #define obstack_alloc(OBSTACK,length)                                  \
                    286: ({ struct obstack *__h = (OBSTACK);                                    \
                    287:    obstack_blank (__h, (length));                                      \
                    288:    obstack_finish (__h); })
                    289: 
                    290: #define obstack_copy(OBSTACK,where,length)                             \
                    291: ({ struct obstack *__h = (OBSTACK);                                    \
                    292:    obstack_grow (__h, (where), (length));                              \
                    293:    obstack_finish (__h); })
                    294: 
                    295: #define obstack_copy0(OBSTACK,where,length)                            \
                    296: ({ struct obstack *__h = (OBSTACK);                                    \
                    297:    obstack_grow0 (__h, (where), (length));                             \
                    298:    obstack_finish (__h); })
                    299: 
                    300: #define obstack_finish(OBSTACK)                                        \
                    301: ({ struct obstack *__o = (OBSTACK);                                    \
                    302:    void *value = (void *) __o->object_base;                            \
                    303:    __o->next_free                                                      \
                    304:      = __INT_TO_PTR ((__PTR_TO_INT (__o->next_free)+__o->alignment_mask)\
                    305:                     & ~ (__o->alignment_mask));                        \
                    306:    ((__o->next_free - (char *)__o->chunk                               \
                    307:      > __o->chunk_limit - (char *)__o->chunk)                          \
                    308:     ? (__o->next_free = __o->chunk_limit) : 0);                                \
                    309:    __o->object_base = __o->next_free;                                  \
                    310:    value; })
                    311: 
                    312: #define obstack_free(OBSTACK, OBJ)                                     \
                    313: ({ struct obstack *__o = (OBSTACK);                                    \
                    314:    void *__obj = (OBJ);                                                        \
                    315:    if (__obj > (void *)__o->chunk && __obj < (void *)__o->chunk_limit)  \
                    316:      __o->next_free = __o->object_base = __obj;                                \
                    317:    else (obstack_free) (__o, __obj); })
                    318: 
                    319: #else /* not __GNUC__ or not __STDC__ */
                    320: 
                    321: #define obstack_object_size(h) \
                    322:  (unsigned) ((h)->next_free - (h)->object_base)
                    323: 
                    324: #define obstack_room(h)                \
                    325:  (unsigned) ((h)->chunk_limit - (h)->next_free)
                    326: 
                    327: #define obstack_grow(h,where,length)                                   \
                    328: ( (h)->temp = (length),                                                        \
                    329:   (((h)->next_free + (h)->temp > (h)->chunk_limit)                     \
                    330:    ? _obstack_newchunk ((h), (h)->temp) : 0),                          \
                    331:   bcopy (where, (h)->next_free, (h)->temp),                            \
                    332:   (h)->next_free += (h)->temp)
                    333: 
                    334: #define obstack_grow0(h,where,length)                                  \
                    335: ( (h)->temp = (length),                                                        \
                    336:   (((h)->next_free + (h)->temp + 1 > (h)->chunk_limit)                 \
                    337:    ? _obstack_newchunk ((h), (h)->temp + 1) : 0),                      \
                    338:   bcopy (where, (h)->next_free, (h)->temp),                            \
                    339:   (h)->next_free += (h)->temp,                                         \
                    340:   *((h)->next_free)++ = 0)
                    341: 
                    342: #define obstack_1grow(h,datum)                                         \
                    343: ( (((h)->next_free + 1 > (h)->chunk_limit)                             \
                    344:    ? _obstack_newchunk ((h), 1) : 0),                                  \
                    345:   *((h)->next_free)++ = (datum))
                    346: 
                    347: #define obstack_ptr_grow(h,datum)                                      \
                    348: ( (((h)->next_free + sizeof (char *) > (h)->chunk_limit)               \
                    349:    ? _obstack_newchunk ((h), sizeof (char *)) : 0),                    \
                    350:   *((char **)(h)->next_free)++ = ((char *)datum))
                    351: 
                    352: #define obstack_int_grow(h,datum)                                      \
                    353: ( (((h)->next_free + sizeof (int) > (h)->chunk_limit)                  \
                    354:    ? _obstack_newchunk ((h), sizeof (int)) : 0),                       \
                    355:   *((int *)(h)->next_free)++ = ((int)datum))
                    356: 
                    357: #define obstack_ptr_grow_fast(h,aptr) (*((char **)(h)->next_free)++ = (char *)aptr)
                    358: #define obstack_int_grow_fast(h,aint) (*((int *)(h)->next_free)++ = (int)aint)
                    359: 
                    360: #define obstack_blank(h,length)                                                \
                    361: ( (h)->temp = (length),                                                        \
                    362:   (((h)->next_free + (h)->temp > (h)->chunk_limit)                     \
                    363:    ? _obstack_newchunk ((h), (h)->temp) : 0),                          \
                    364:   (h)->next_free += (h)->temp)
                    365: 
                    366: #define obstack_alloc(h,length)                                                \
                    367:  (obstack_blank ((h), (length)), obstack_finish ((h)))
                    368: 
                    369: #define obstack_copy(h,where,length)                                   \
                    370:  (obstack_grow ((h), (where), (length)), obstack_finish ((h)))
                    371: 
                    372: #define obstack_copy0(h,where,length)                                  \
                    373:  (obstack_grow0 ((h), (where), (length)), obstack_finish ((h)))
                    374: 
                    375: #define obstack_finish(h)                                              \
                    376: ( (h)->temp = __PTR_TO_INT ((h)->object_base),                         \
                    377:   (h)->next_free                                                       \
                    378:     = __INT_TO_PTR ((__PTR_TO_INT ((h)->next_free)+(h)->alignment_mask)        \
                    379:                    & ~ ((h)->alignment_mask)),                         \
                    380:   (((h)->next_free - (char *)(h)->chunk                                        \
                    381:     > (h)->chunk_limit - (char *)(h)->chunk)                           \
                    382:    ? ((h)->next_free = (h)->chunk_limit) : 0),                         \
                    383:   (h)->object_base = (h)->next_free,                                   \
                    384:   __INT_TO_PTR ((h)->temp))
                    385: 
                    386: #ifdef __STDC__
                    387: #define obstack_free(h,obj)                                            \
                    388: ( (h)->temp = (char *)(obj) - (char *) (h)->chunk,                     \
                    389:   (((h)->temp >= 0 && (h)->temp < (h)->chunk_limit - (char *) (h)->chunk)\
                    390:    ? (int) ((h)->next_free = (h)->object_base                          \
                    391:            = (h)->temp + (char *) (h)->chunk)                          \
                    392:    : ((obstack_free) ((h), (h)->temp + (char *) (h)->chunk), 0)))
                    393: #else
                    394: #define obstack_free(h,obj)                                            \
                    395: ( (h)->temp = (char *)(obj) - (char *) (h)->chunk,                     \
                    396:   (((h)->temp >= 0 && (h)->temp < (h)->chunk_limit - (char *) (h)->chunk)\
                    397:    ? (int) ((h)->next_free = (h)->object_base                          \
                    398:            = (h)->temp + (char *) (h)->chunk)                          \
                    399:    : (int) _obstack_free ((h), (h)->temp + (char *) (h)->chunk)))
                    400: #endif
                    401: 
                    402: #endif /* not __GNUC__ or not __STDC__ */
                    403: 
                    404: #endif /* not __OBSTACKS__ */
                    405: 

unix.superglobalmegacorp.com

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