Annotation of gcc/obstack.c, revision 1.1.1.5

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

unix.superglobalmegacorp.com

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