Annotation of GNUtools/debug/gdb/libiberty/obstack.c, revision 1.1.1.1

1.1       root        1: /* obstack.c - subroutines used implicitly by object stack macros
                      2:    Copyright (C) 1988 Free Software Foundation, Inc.
                      3: 
                      4: This file is part of the libiberty library.
                      5: Libiberty is free software; you can redistribute it and/or
                      6: modify it under the terms of the GNU Library General Public
                      7: License as published by the Free Software Foundation; either
                      8: version 2 of the License, or (at your option) any later version.
                      9: 
                     10: Libiberty 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: Library General Public License for more details.
                     14: 
                     15: You should have received a copy of the GNU Library General Public
                     16: License along with libiberty; see the file COPYING.LIB.  If
                     17: not, write to the Free Software Foundation, Inc., 675 Mass Ave,
                     18: Cambridge, MA 02139, USA.  */
                     19: 
                     20: #include "obstack.h"
                     21: 
                     22: #ifdef __STDC__
                     23: #define POINTER void *
                     24: #else
                     25: #define POINTER char *
                     26: #endif
                     27: 
                     28: /* Determine default alignment.  */
                     29: struct fooalign {char x; double d;};
                     30: #define DEFAULT_ALIGNMENT  \
                     31:   ((PTR_INT_TYPE) ((char *)&((struct fooalign *) 0)->d - (char *)0))
                     32: /* If malloc were really smart, it would round addresses to DEFAULT_ALIGNMENT.
                     33:    But in fact it might be less smart and round addresses to as much as
                     34:    DEFAULT_ROUNDING.  So we prepare for it to do that.  */
                     35: union fooround {long x; double d;};
                     36: #define DEFAULT_ROUNDING (sizeof (union fooround))
                     37: 
                     38: /* When we copy a long block of data, this is the unit to do it with.
                     39:    On some machines, copying successive ints does not work;
                     40:    in such a case, redefine COPYING_UNIT to `long' (if that works)
                     41:    or `char' as a last resort.  */
                     42: #ifndef COPYING_UNIT
                     43: #define COPYING_UNIT int
                     44: #endif
                     45: 
                     46: /* The non-GNU-C macros copy the obstack into this global variable
                     47:    to avoid multiple evaluation.  */
                     48: 
                     49: struct obstack *_obstack;
                     50: 
                     51: /* Define a macro that either calls functions with the traditional malloc/free
                     52:    calling interface, or calls functions with the mmalloc/mfree interface
                     53:    (that adds an extra first argument), based on the state of use_extra_arg.
                     54:    For free, do not use ?:, since some compilers, like the MIPS compilers,
                     55:    do not allow (expr) ? void : void.  */
                     56: 
                     57: #define CALL_CHUNKFUN(h, size) \
                     58:   (((h) -> use_extra_arg) \
                     59:    ? (*(h)->chunkfun) ((h)->extra_arg, (size)) \
                     60:    : (*(h)->chunkfun) ((size)))
                     61: 
                     62: #define CALL_FREEFUN(h, old_chunk) \
                     63:   do { \
                     64:     if ((h) -> use_extra_arg) \
                     65:       (*(h)->freefun) ((h)->extra_arg, (old_chunk)); \
                     66:     else \
                     67:       (*(h)->freefun) ((old_chunk)); \
                     68:   } while (0)
                     69: 
                     70: 
                     71: /* Initialize an obstack H for use.  Specify chunk size SIZE (0 means default).
                     72:    Objects start on multiples of ALIGNMENT (0 means use default).
                     73:    CHUNKFUN is the function to use to allocate chunks,
                     74:    and FREEFUN the function to free them.  */
                     75: 
                     76: void
                     77: _obstack_begin (h, size, alignment, chunkfun, freefun)
                     78:      struct obstack *h;
                     79:      int size;
                     80:      int alignment;
                     81:      POINTER (*chunkfun) ();
                     82:      void (*freefun) ();
                     83: {
                     84:   register struct _obstack_chunk* chunk; /* points to new chunk */
                     85: 
                     86:   if (alignment == 0)
                     87:     alignment = DEFAULT_ALIGNMENT;
                     88:   if (size == 0)
                     89:     /* Default size is what GNU malloc can fit in a 4096-byte block.  */
                     90:     {
                     91:       /* 12 is sizeof (mhead) and 4 is EXTRA from GNU malloc.
                     92:         Use the values for range checking, because if range checking is off,
                     93:         the extra bytes won't be missed terribly, but if range checking is on
                     94:         and we used a larger request, a whole extra 4096 bytes would be
                     95:         allocated.
                     96: 
                     97:         These number are irrelevant to the new GNU malloc.  I suspect it is
                     98:         less sensitive to the size of the request.  */
                     99:       int extra = ((((12 + DEFAULT_ROUNDING - 1) & ~(DEFAULT_ROUNDING - 1))
                    100:                    + 4 + DEFAULT_ROUNDING - 1)
                    101:                   & ~(DEFAULT_ROUNDING - 1));
                    102:       size = 4096 - extra;
                    103:     }
                    104: 
                    105:   h->chunkfun = (struct _obstack_chunk * (*)()) chunkfun;
                    106:   h->freefun = freefun;
                    107:   h->chunk_size = size;
                    108:   h->alignment_mask = alignment - 1;
                    109:   h->use_extra_arg = 0;
                    110: 
                    111:   chunk = h->chunk = CALL_CHUNKFUN (h, h -> chunk_size);
                    112:   h->next_free = h->object_base = chunk->contents;
                    113:   h->chunk_limit = chunk->limit
                    114:     = (char *) chunk + h->chunk_size;
                    115:   chunk->prev = 0;
                    116:   /* The initial chunk now contains no empty object.  */
                    117:   h->maybe_empty_object = 0;
                    118: }
                    119: 
                    120: void
                    121: _obstack_begin_1 (h, size, alignment, chunkfun, freefun, arg)
                    122:      struct obstack *h;
                    123:      int size;
                    124:      int alignment;
                    125:      POINTER (*chunkfun) ();
                    126:      void (*freefun) ();
                    127:      POINTER arg;
                    128: {
                    129:   register struct _obstack_chunk* chunk; /* points to new chunk */
                    130: 
                    131:   if (alignment == 0)
                    132:     alignment = DEFAULT_ALIGNMENT;
                    133:   if (size == 0)
                    134:     /* Default size is what GNU malloc can fit in a 4096-byte block.  */
                    135:     {
                    136:       /* 12 is sizeof (mhead) and 4 is EXTRA from GNU malloc.
                    137:         Use the values for range checking, because if range checking is off,
                    138:         the extra bytes won't be missed terribly, but if range checking is on
                    139:         and we used a larger request, a whole extra 4096 bytes would be
                    140:         allocated.
                    141: 
                    142:         These number are irrelevant to the new GNU malloc.  I suspect it is
                    143:         less sensitive to the size of the request.  */
                    144:       int extra = ((((12 + DEFAULT_ROUNDING - 1) & ~(DEFAULT_ROUNDING - 1))
                    145:                    + 4 + DEFAULT_ROUNDING - 1)
                    146:                   & ~(DEFAULT_ROUNDING - 1));
                    147:       size = 4096 - extra;
                    148:     }
                    149: 
                    150:   h->chunkfun = (struct _obstack_chunk * (*)()) chunkfun;
                    151:   h->freefun = freefun;
                    152:   h->chunk_size = size;
                    153:   h->alignment_mask = alignment - 1;
                    154:   h->extra_arg = arg;
                    155:   h->use_extra_arg = 1;
                    156: 
                    157:   chunk = h->chunk = CALL_CHUNKFUN (h, h -> chunk_size);
                    158:   h->next_free = h->object_base = chunk->contents;
                    159:   h->chunk_limit = chunk->limit
                    160:     = (char *) chunk + h->chunk_size;
                    161:   chunk->prev = 0;
                    162:   /* The initial chunk now contains no empty object.  */
                    163:   h->maybe_empty_object = 0;
                    164: }
                    165: 
                    166: /* Allocate a new current chunk for the obstack *H
                    167:    on the assumption that LENGTH bytes need to be added
                    168:    to the current object, or a new object of length LENGTH allocated.
                    169:    Copies any partial object from the end of the old chunk
                    170:    to the beginning of the new one.  */
                    171: 
                    172: void
                    173: _obstack_newchunk (h, length)
                    174:      struct obstack *h;
                    175:      int length;
                    176: {
                    177:   register struct _obstack_chunk*      old_chunk = h->chunk;
                    178:   register struct _obstack_chunk*      new_chunk;
                    179:   register long        new_size;
                    180:   register int obj_size = h->next_free - h->object_base;
                    181:   register int i;
                    182:   int already;
                    183: 
                    184:   /* Compute size for new chunk.  */
                    185:   new_size = (obj_size + length) + (obj_size >> 3) + 100;
                    186:   if (new_size < h->chunk_size)
                    187:     new_size = h->chunk_size;
                    188: 
                    189:   /* Allocate and initialize the new chunk.  */
                    190:   new_chunk = h->chunk = CALL_CHUNKFUN (h, new_size);
                    191:   new_chunk->prev = old_chunk;
                    192:   new_chunk->limit = h->chunk_limit = (char *) new_chunk + new_size;
                    193: 
                    194:   /* Move the existing object to the new chunk.
                    195:      Word at a time is fast and is safe if the object
                    196:      is sufficiently aligned.  */
                    197:   if (h->alignment_mask + 1 >= DEFAULT_ALIGNMENT)
                    198:     {
                    199:       for (i = obj_size / sizeof (COPYING_UNIT) - 1;
                    200:           i >= 0; i--)
                    201:        ((COPYING_UNIT *)new_chunk->contents)[i]
                    202:          = ((COPYING_UNIT *)h->object_base)[i];
                    203:       /* We used to copy the odd few remaining bytes as one extra COPYING_UNIT,
                    204:         but that can cross a page boundary on a machine
                    205:         which does not do strict alignment for COPYING_UNITS.  */
                    206:       already = obj_size / sizeof (COPYING_UNIT) * sizeof (COPYING_UNIT);
                    207:     }
                    208:   else
                    209:     already = 0;
                    210:   /* Copy remaining bytes one by one.  */
                    211:   for (i = already; i < obj_size; i++)
                    212:     new_chunk->contents[i] = h->object_base[i];
                    213: 
                    214:   /* If the object just copied was the only data in OLD_CHUNK,
                    215:      free that chunk and remove it from the chain.
                    216:      But not if that chunk might contain an empty object.  */
                    217:   if (h->object_base == old_chunk->contents && ! h->maybe_empty_object)
                    218:     {
                    219:       new_chunk->prev = old_chunk->prev;
                    220:       CALL_FREEFUN (h, old_chunk);
                    221:     }
                    222: 
                    223:   h->object_base = new_chunk->contents;
                    224:   h->next_free = h->object_base + obj_size;
                    225:   /* The new chunk certainly contains no empty object yet.  */
                    226:   h->maybe_empty_object = 0;
                    227: }
                    228: 
                    229: /* Return nonzero if object OBJ has been allocated from obstack H.
                    230:    This is here for debugging.
                    231:    If you use it in a program, you are probably losing.  */
                    232: 
                    233: int
                    234: _obstack_allocated_p (h, obj)
                    235:      struct obstack *h;
                    236:      POINTER obj;
                    237: {
                    238:   register struct _obstack_chunk*  lp; /* below addr of any objects in this chunk */
                    239:   register struct _obstack_chunk*  plp;        /* point to previous chunk if any */
                    240: 
                    241:   lp = (h)->chunk;
                    242:   /* We use >= rather than > since the object cannot be exactly at
                    243:      the beginning of the chunk but might be an empty object exactly
                    244:      at the end of an adjacent chunk. */
                    245:   while (lp != 0 && ((POINTER)lp >= obj || (POINTER)(lp)->limit < obj))
                    246:     {
                    247:       plp = lp->prev;
                    248:       lp = plp;
                    249:     }
                    250:   return lp != 0;
                    251: }
                    252: 
                    253: /* Free objects in obstack H, including OBJ and everything allocate
                    254:    more recently than OBJ.  If OBJ is zero, free everything in H.  */
                    255: 
                    256: #undef obstack_free
                    257: 
                    258: /* This function has two names with identical definitions.
                    259:    This is the first one, called from non-ANSI code.  */
                    260: 
                    261: void
                    262: _obstack_free (h, obj)
                    263:      struct obstack *h;
                    264:      POINTER obj;
                    265: {
                    266:   register struct _obstack_chunk*  lp; /* below addr of any objects in this chunk */
                    267:   register struct _obstack_chunk*  plp;        /* point to previous chunk if any */
                    268: 
                    269:   lp = h->chunk;
                    270:   /* We use >= because there cannot be an object at the beginning of a chunk.
                    271:      But there can be an empty object at that address
                    272:      at the end of another chunk.  */
                    273:   while (lp != 0 && ((POINTER)lp >= obj || (POINTER)(lp)->limit < obj))
                    274:     {
                    275:       plp = lp->prev;
                    276:       CALL_FREEFUN (h, lp);
                    277:       lp = plp;
                    278:       /* If we switch chunks, we can't tell whether the new current
                    279:         chunk contains an empty object, so assume that it may.  */
                    280:       h->maybe_empty_object = 1;
                    281:     }
                    282:   if (lp)
                    283:     {
                    284:       h->object_base = h->next_free = (char *)(obj);
                    285:       h->chunk_limit = lp->limit;
                    286:       h->chunk = lp;
                    287:     }
                    288:   else if (obj != 0)
                    289:     /* obj is not in any of the chunks! */
                    290:     abort ();
                    291: }
                    292: 
                    293: /* This function is used from ANSI code.  */
                    294: 
                    295: void
                    296: obstack_free (h, obj)
                    297:      struct obstack *h;
                    298:      POINTER obj;
                    299: {
                    300:   register struct _obstack_chunk*  lp; /* below addr of any objects in this chunk */
                    301:   register struct _obstack_chunk*  plp;        /* point to previous chunk if any */
                    302: 
                    303:   lp = h->chunk;
                    304:   /* We use >= because there cannot be an object at the beginning of a chunk.
                    305:      But there can be an empty object at that address
                    306:      at the end of another chunk.  */
                    307:   while (lp != 0 && ((POINTER)lp >= obj || (POINTER)(lp)->limit < obj))
                    308:     {
                    309:       plp = lp->prev;
                    310:       CALL_FREEFUN (h, lp);
                    311:       lp = plp;
                    312:       /* If we switch chunks, we can't tell whether the new current
                    313:         chunk contains an empty object, so assume that it may.  */
                    314:       h->maybe_empty_object = 1;
                    315:     }
                    316:   if (lp)
                    317:     {
                    318:       h->object_base = h->next_free = (char *)(obj);
                    319:       h->chunk_limit = lp->limit;
                    320:       h->chunk = lp;
                    321:     }
                    322:   else if (obj != 0)
                    323:     /* obj is not in any of the chunks! */
                    324:     abort ();
                    325: }
                    326: 
                    327: #if 0
                    328: /* These are now turned off because the applications do not use it
                    329:    and it uses bcopy via obstack_grow, which causes trouble on sysV.  */
                    330: 
                    331: /* Now define the functional versions of the obstack macros.
                    332:    Define them to simply use the corresponding macros to do the job.  */
                    333: 
                    334: #ifdef __STDC__
                    335: /* These function definitions do not work with non-ANSI preprocessors;
                    336:    they won't pass through the macro names in parentheses.  */
                    337: 
                    338: /* The function names appear in parentheses in order to prevent
                    339:    the macro-definitions of the names from being expanded there.  */
                    340: 
                    341: POINTER (obstack_base) (obstack)
                    342:      struct obstack *obstack;
                    343: {
                    344:   return obstack_base (obstack);
                    345: }
                    346: 
                    347: POINTER (obstack_next_free) (obstack)
                    348:      struct obstack *obstack;
                    349: {
                    350:   return obstack_next_free (obstack);
                    351: }
                    352: 
                    353: int (obstack_object_size) (obstack)
                    354:      struct obstack *obstack;
                    355: {
                    356:   return obstack_object_size (obstack);
                    357: }
                    358: 
                    359: int (obstack_room) (obstack)
                    360:      struct obstack *obstack;
                    361: {
                    362:   return obstack_room (obstack);
                    363: }
                    364: 
                    365: void (obstack_grow) (obstack, pointer, length)
                    366:      struct obstack *obstack;
                    367:      POINTER pointer;
                    368:      int length;
                    369: {
                    370:   obstack_grow (obstack, pointer, length);
                    371: }
                    372: 
                    373: void (obstack_grow0) (obstack, pointer, length)
                    374:      struct obstack *obstack;
                    375:      POINTER pointer;
                    376:      int length;
                    377: {
                    378:   obstack_grow0 (obstack, pointer, length);
                    379: }
                    380: 
                    381: void (obstack_1grow) (obstack, character)
                    382:      struct obstack *obstack;
                    383:      int character;
                    384: {
                    385:   obstack_1grow (obstack, character);
                    386: }
                    387: 
                    388: void (obstack_blank) (obstack, length)
                    389:      struct obstack *obstack;
                    390:      int length;
                    391: {
                    392:   obstack_blank (obstack, length);
                    393: }
                    394: 
                    395: void (obstack_1grow_fast) (obstack, character)
                    396:      struct obstack *obstack;
                    397:      int character;
                    398: {
                    399:   obstack_1grow_fast (obstack, character);
                    400: }
                    401: 
                    402: void (obstack_blank_fast) (obstack, length)
                    403:      struct obstack *obstack;
                    404:      int length;
                    405: {
                    406:   obstack_blank_fast (obstack, length);
                    407: }
                    408: 
                    409: POINTER (obstack_finish) (obstack)
                    410:      struct obstack *obstack;
                    411: {
                    412:   return obstack_finish (obstack);
                    413: }
                    414: 
                    415: POINTER (obstack_alloc) (obstack, length)
                    416:      struct obstack *obstack;
                    417:      int length;
                    418: {
                    419:   return obstack_alloc (obstack, length);
                    420: }
                    421: 
                    422: POINTER (obstack_copy) (obstack, pointer, length)
                    423:      struct obstack *obstack;
                    424:      POINTER pointer;
                    425:      int length;
                    426: {
                    427:   return obstack_copy (obstack, pointer, length);
                    428: }
                    429: 
                    430: POINTER (obstack_copy0) (obstack, pointer, length)
                    431:      struct obstack *obstack;
                    432:      POINTER pointer;
                    433:      int length;
                    434: {
                    435:   return obstack_copy0 (obstack, pointer, length);
                    436: }
                    437: 
                    438: #endif /* __STDC__ */
                    439: 
                    440: #endif /* 0 */

unix.superglobalmegacorp.com

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