Back to index

glibc  2.9
obstack.c
Go to the documentation of this file.
00001 /* obstack.c - subroutines used implicitly by object stack macros
00002    Copyright (C) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1996, 1997, 1998,
00003    1999, 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
00004    This file is part of the GNU C Library.
00005 
00006    The GNU C Library is free software; you can redistribute it and/or
00007    modify it under the terms of the GNU Lesser General Public
00008    License as published by the Free Software Foundation; either
00009    version 2.1 of the License, or (at your option) any later version.
00010 
00011    The GNU C Library is distributed in the hope that it will be useful,
00012    but WITHOUT ANY WARRANTY; without even the implied warranty of
00013    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014    Lesser General Public License for more details.
00015 
00016    You should have received a copy of the GNU Lesser General Public
00017    License along with the GNU C Library; if not, write to the Free
00018    Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00019    Boston, MA 02110-1301, USA.  */
00020 
00021 
00022 #ifdef HAVE_CONFIG_H
00023 # include <config.h>
00024 #endif
00025 
00026 #ifdef _LIBC
00027 # include <obstack.h>
00028 # include <shlib-compat.h>
00029 #else
00030 # include "obstack.h"
00031 #endif
00032 
00033 /* NOTE BEFORE MODIFYING THIS FILE: This version number must be
00034    incremented whenever callers compiled using an old obstack.h can no
00035    longer properly call the functions in this obstack.c.  */
00036 #define OBSTACK_INTERFACE_VERSION 1
00037 
00038 /* Comment out all this code if we are using the GNU C Library, and are not
00039    actually compiling the library itself, and the installed library
00040    supports the same library interface we do.  This code is part of the GNU
00041    C Library, but also included in many other GNU distributions.  Compiling
00042    and linking in this code is a waste when using the GNU C library
00043    (especially if it is a shared library).  Rather than having every GNU
00044    program understand `configure --with-gnu-libc' and omit the object
00045    files, it is simpler to just do this in the source for each such file.  */
00046 
00047 #include <stdio.h>          /* Random thing to get __GNU_LIBRARY__.  */
00048 #if !defined _LIBC && defined __GNU_LIBRARY__ && __GNU_LIBRARY__ > 1
00049 # include <gnu-versions.h>
00050 # if _GNU_OBSTACK_INTERFACE_VERSION == OBSTACK_INTERFACE_VERSION
00051 #  define ELIDE_CODE
00052 # endif
00053 #endif
00054 
00055 #include <stddef.h>
00056 
00057 #ifndef ELIDE_CODE
00058 
00059 
00060 # if HAVE_INTTYPES_H
00061 #  include <inttypes.h>
00062 # endif
00063 # if HAVE_STDINT_H || defined _LIBC
00064 #  include <stdint.h>
00065 # endif
00066 
00067 /* Determine default alignment.  */
00068 union fooround
00069 {
00070   uintmax_t i;
00071   long double d;
00072   void *p;
00073 };
00074 struct fooalign
00075 {
00076   char c;
00077   union fooround u;
00078 };
00079 /* If malloc were really smart, it would round addresses to DEFAULT_ALIGNMENT.
00080    But in fact it might be less smart and round addresses to as much as
00081    DEFAULT_ROUNDING.  So we prepare for it to do that.  */
00082 enum
00083   {
00084     DEFAULT_ALIGNMENT = offsetof (struct fooalign, u),
00085     DEFAULT_ROUNDING = sizeof (union fooround)
00086   };
00087 
00088 /* When we copy a long block of data, this is the unit to do it with.
00089    On some machines, copying successive ints does not work;
00090    in such a case, redefine COPYING_UNIT to `long' (if that works)
00091    or `char' as a last resort.  */
00092 # ifndef COPYING_UNIT
00093 #  define COPYING_UNIT int
00094 # endif
00095 
00096 
00097 /* The functions allocating more room by calling `obstack_chunk_alloc'
00098    jump to the handler pointed to by `obstack_alloc_failed_handler'.
00099    This can be set to a user defined function which should either
00100    abort gracefully or use longjump - but shouldn't return.  This
00101    variable by default points to the internal function
00102    `print_and_abort'.  */
00103 static void print_and_abort (void);
00104 void (*obstack_alloc_failed_handler) (void) = print_and_abort;
00105 
00106 /* Exit value used when `print_and_abort' is used.  */
00107 # include <stdlib.h>
00108 # ifdef _LIBC
00109 int obstack_exit_failure = EXIT_FAILURE;
00110 # else
00111 #  include "exitfail.h"
00112 #  define obstack_exit_failure exit_failure
00113 # endif
00114 
00115 # ifdef _LIBC
00116 #  if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_3_4)
00117 /* A looong time ago (before 1994, anyway; we're not sure) this global variable
00118    was used by non-GNU-C macros to avoid multiple evaluation.  The GNU C
00119    library still exports it because somebody might use it.  */
00120 struct obstack *_obstack_compat;
00121 compat_symbol (libc, _obstack_compat, _obstack, GLIBC_2_0);
00122 #  endif
00123 # endif
00124 
00125 /* Define a macro that either calls functions with the traditional malloc/free
00126    calling interface, or calls functions with the mmalloc/mfree interface
00127    (that adds an extra first argument), based on the state of use_extra_arg.
00128    For free, do not use ?:, since some compilers, like the MIPS compilers,
00129    do not allow (expr) ? void : void.  */
00130 
00131 # define CALL_CHUNKFUN(h, size) \
00132   (((h) -> use_extra_arg) \
00133    ? (*(h)->chunkfun) ((h)->extra_arg, (size)) \
00134    : (*(struct _obstack_chunk *(*) (long)) (h)->chunkfun) ((size)))
00135 
00136 # define CALL_FREEFUN(h, old_chunk) \
00137   do { \
00138     if ((h) -> use_extra_arg) \
00139       (*(h)->freefun) ((h)->extra_arg, (old_chunk)); \
00140     else \
00141       (*(void (*) (void *)) (h)->freefun) ((old_chunk)); \
00142   } while (0)
00143 
00144 
00145 /* Initialize an obstack H for use.  Specify chunk size SIZE (0 means default).
00146    Objects start on multiples of ALIGNMENT (0 means use default).
00147    CHUNKFUN is the function to use to allocate chunks,
00148    and FREEFUN the function to free them.
00149 
00150    Return nonzero if successful, calls obstack_alloc_failed_handler if
00151    allocation fails.  */
00152 
00153 int
00154 _obstack_begin (struct obstack *h,
00155               int size, int alignment,
00156               void *(*chunkfun) (long),
00157               void (*freefun) (void *))
00158 {
00159   register struct _obstack_chunk *chunk; /* points to new chunk */
00160 
00161   if (alignment == 0)
00162     alignment = DEFAULT_ALIGNMENT;
00163   if (size == 0)
00164     /* Default size is what GNU malloc can fit in a 4096-byte block.  */
00165     {
00166       /* 12 is sizeof (mhead) and 4 is EXTRA from GNU malloc.
00167         Use the values for range checking, because if range checking is off,
00168         the extra bytes won't be missed terribly, but if range checking is on
00169         and we used a larger request, a whole extra 4096 bytes would be
00170         allocated.
00171 
00172         These number are irrelevant to the new GNU malloc.  I suspect it is
00173         less sensitive to the size of the request.  */
00174       int extra = ((((12 + DEFAULT_ROUNDING - 1) & ~(DEFAULT_ROUNDING - 1))
00175                   + 4 + DEFAULT_ROUNDING - 1)
00176                  & ~(DEFAULT_ROUNDING - 1));
00177       size = 4096 - extra;
00178     }
00179 
00180   h->chunkfun = (struct _obstack_chunk * (*)(void *, long)) chunkfun;
00181   h->freefun = (void (*) (void *, struct _obstack_chunk *)) freefun;
00182   h->chunk_size = size;
00183   h->alignment_mask = alignment - 1;
00184   h->use_extra_arg = 0;
00185 
00186   chunk = h->chunk = CALL_CHUNKFUN (h, h -> chunk_size);
00187   if (!chunk)
00188     (*obstack_alloc_failed_handler) ();
00189   h->next_free = h->object_base = __PTR_ALIGN ((char *) chunk, chunk->contents,
00190                                           alignment - 1);
00191   h->chunk_limit = chunk->limit
00192     = (char *) chunk + h->chunk_size;
00193   chunk->prev = 0;
00194   /* The initial chunk now contains no empty object.  */
00195   h->maybe_empty_object = 0;
00196   h->alloc_failed = 0;
00197   return 1;
00198 }
00199 
00200 int
00201 _obstack_begin_1 (struct obstack *h, int size, int alignment,
00202                 void *(*chunkfun) (void *, long),
00203                 void (*freefun) (void *, void *),
00204                 void *arg)
00205 {
00206   register struct _obstack_chunk *chunk; /* points to new chunk */
00207 
00208   if (alignment == 0)
00209     alignment = DEFAULT_ALIGNMENT;
00210   if (size == 0)
00211     /* Default size is what GNU malloc can fit in a 4096-byte block.  */
00212     {
00213       /* 12 is sizeof (mhead) and 4 is EXTRA from GNU malloc.
00214         Use the values for range checking, because if range checking is off,
00215         the extra bytes won't be missed terribly, but if range checking is on
00216         and we used a larger request, a whole extra 4096 bytes would be
00217         allocated.
00218 
00219         These number are irrelevant to the new GNU malloc.  I suspect it is
00220         less sensitive to the size of the request.  */
00221       int extra = ((((12 + DEFAULT_ROUNDING - 1) & ~(DEFAULT_ROUNDING - 1))
00222                   + 4 + DEFAULT_ROUNDING - 1)
00223                  & ~(DEFAULT_ROUNDING - 1));
00224       size = 4096 - extra;
00225     }
00226 
00227   h->chunkfun = (struct _obstack_chunk * (*)(void *,long)) chunkfun;
00228   h->freefun = (void (*) (void *, struct _obstack_chunk *)) freefun;
00229   h->chunk_size = size;
00230   h->alignment_mask = alignment - 1;
00231   h->extra_arg = arg;
00232   h->use_extra_arg = 1;
00233 
00234   chunk = h->chunk = CALL_CHUNKFUN (h, h -> chunk_size);
00235   if (!chunk)
00236     (*obstack_alloc_failed_handler) ();
00237   h->next_free = h->object_base = __PTR_ALIGN ((char *) chunk, chunk->contents,
00238                                           alignment - 1);
00239   h->chunk_limit = chunk->limit
00240     = (char *) chunk + h->chunk_size;
00241   chunk->prev = 0;
00242   /* The initial chunk now contains no empty object.  */
00243   h->maybe_empty_object = 0;
00244   h->alloc_failed = 0;
00245   return 1;
00246 }
00247 
00248 /* Allocate a new current chunk for the obstack *H
00249    on the assumption that LENGTH bytes need to be added
00250    to the current object, or a new object of length LENGTH allocated.
00251    Copies any partial object from the end of the old chunk
00252    to the beginning of the new one.  */
00253 
00254 void
00255 _obstack_newchunk (struct obstack *h, int length)
00256 {
00257   register struct _obstack_chunk *old_chunk = h->chunk;
00258   register struct _obstack_chunk *new_chunk;
00259   register long      new_size;
00260   register long obj_size = h->next_free - h->object_base;
00261   register long i;
00262   long already;
00263   char *object_base;
00264 
00265   /* Compute size for new chunk.  */
00266   new_size = (obj_size + length) + (obj_size >> 3) + h->alignment_mask + 100;
00267   if (new_size < h->chunk_size)
00268     new_size = h->chunk_size;
00269 
00270   /* Allocate and initialize the new chunk.  */
00271   new_chunk = CALL_CHUNKFUN (h, new_size);
00272   if (!new_chunk)
00273     (*obstack_alloc_failed_handler) ();
00274   h->chunk = new_chunk;
00275   new_chunk->prev = old_chunk;
00276   new_chunk->limit = h->chunk_limit = (char *) new_chunk + new_size;
00277 
00278   /* Compute an aligned object_base in the new chunk */
00279   object_base =
00280     __PTR_ALIGN ((char *) new_chunk, new_chunk->contents, h->alignment_mask);
00281 
00282   /* Move the existing object to the new chunk.
00283      Word at a time is fast and is safe if the object
00284      is sufficiently aligned.  */
00285   if (h->alignment_mask + 1 >= DEFAULT_ALIGNMENT)
00286     {
00287       for (i = obj_size / sizeof (COPYING_UNIT) - 1;
00288           i >= 0; i--)
00289        ((COPYING_UNIT *)object_base)[i]
00290          = ((COPYING_UNIT *)h->object_base)[i];
00291       /* We used to copy the odd few remaining bytes as one extra COPYING_UNIT,
00292         but that can cross a page boundary on a machine
00293         which does not do strict alignment for COPYING_UNITS.  */
00294       already = obj_size / sizeof (COPYING_UNIT) * sizeof (COPYING_UNIT);
00295     }
00296   else
00297     already = 0;
00298   /* Copy remaining bytes one by one.  */
00299   for (i = already; i < obj_size; i++)
00300     object_base[i] = h->object_base[i];
00301 
00302   /* If the object just copied was the only data in OLD_CHUNK,
00303      free that chunk and remove it from the chain.
00304      But not if that chunk might contain an empty object.  */
00305   if (! h->maybe_empty_object
00306       && (h->object_base
00307          == __PTR_ALIGN ((char *) old_chunk, old_chunk->contents,
00308                        h->alignment_mask)))
00309     {
00310       new_chunk->prev = old_chunk->prev;
00311       CALL_FREEFUN (h, old_chunk);
00312     }
00313 
00314   h->object_base = object_base;
00315   h->next_free = h->object_base + obj_size;
00316   /* The new chunk certainly contains no empty object yet.  */
00317   h->maybe_empty_object = 0;
00318 }
00319 # ifdef _LIBC
00320 libc_hidden_def (_obstack_newchunk)
00321 # endif
00322 
00323 /* Return nonzero if object OBJ has been allocated from obstack H.
00324    This is here for debugging.
00325    If you use it in a program, you are probably losing.  */
00326 
00327 /* Suppress -Wmissing-prototypes warning.  We don't want to declare this in
00328    obstack.h because it is just for debugging.  */
00329 int _obstack_allocated_p (struct obstack *h, void *obj);
00330 
00331 int
00332 _obstack_allocated_p (struct obstack *h, void *obj)
00333 {
00334   register struct _obstack_chunk *lp;     /* below addr of any objects in this chunk */
00335   register struct _obstack_chunk *plp;    /* point to previous chunk if any */
00336 
00337   lp = (h)->chunk;
00338   /* We use >= rather than > since the object cannot be exactly at
00339      the beginning of the chunk but might be an empty object exactly
00340      at the end of an adjacent chunk.  */
00341   while (lp != 0 && ((void *) lp >= obj || (void *) (lp)->limit < obj))
00342     {
00343       plp = lp->prev;
00344       lp = plp;
00345     }
00346   return lp != 0;
00347 }
00348 
00349 /* Free objects in obstack H, including OBJ and everything allocate
00350    more recently than OBJ.  If OBJ is zero, free everything in H.  */
00351 
00352 # undef obstack_free
00353 
00354 void
00355 obstack_free (struct obstack *h, void *obj)
00356 {
00357   register struct _obstack_chunk *lp;     /* below addr of any objects in this chunk */
00358   register struct _obstack_chunk *plp;    /* point to previous chunk if any */
00359 
00360   lp = h->chunk;
00361   /* We use >= because there cannot be an object at the beginning of a chunk.
00362      But there can be an empty object at that address
00363      at the end of another chunk.  */
00364   while (lp != 0 && ((void *) lp >= obj || (void *) (lp)->limit < obj))
00365     {
00366       plp = lp->prev;
00367       CALL_FREEFUN (h, lp);
00368       lp = plp;
00369       /* If we switch chunks, we can't tell whether the new current
00370         chunk contains an empty object, so assume that it may.  */
00371       h->maybe_empty_object = 1;
00372     }
00373   if (lp)
00374     {
00375       h->object_base = h->next_free = (char *) (obj);
00376       h->chunk_limit = lp->limit;
00377       h->chunk = lp;
00378     }
00379   else if (obj != 0)
00380     /* obj is not in any of the chunks! */
00381     abort ();
00382 }
00383 
00384 # ifdef _LIBC
00385 /* Older versions of libc used a function _obstack_free intended to be
00386    called by non-GCC compilers.  */
00387 strong_alias (obstack_free, _obstack_free)
00388 # endif
00389 
00390 int
00391 _obstack_memory_used (struct obstack *h)
00392 {
00393   register struct _obstack_chunk* lp;
00394   register int nbytes = 0;
00395 
00396   for (lp = h->chunk; lp != 0; lp = lp->prev)
00397     {
00398       nbytes += lp->limit - (char *) lp;
00399     }
00400   return nbytes;
00401 }
00402 
00403 /* Define the error handler.  */
00404 # ifdef _LIBC
00405 #  include <libintl.h>
00406 # else
00407 #  include "gettext.h"
00408 # endif
00409 # ifndef _
00410 #  define _(msgid) gettext (msgid)
00411 # endif
00412 
00413 # ifdef _LIBC
00414 #  include <libio/iolibio.h>
00415 # endif
00416 
00417 # ifndef __attribute__
00418 /* This feature is available in gcc versions 2.5 and later.  */
00419 #  if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 5)
00420 #   define __attribute__(Spec) /* empty */
00421 #  endif
00422 # endif
00423 
00424 static void
00425 __attribute__ ((noreturn))
00426 print_and_abort (void)
00427 {
00428   /* Don't change any of these strings.  Yes, it would be possible to add
00429      the newline to the string and use fputs or so.  But this must not
00430      happen because the "memory exhausted" message appears in other places
00431      like this and the translation should be reused instead of creating
00432      a very similar string which requires a separate translation.  */
00433 # ifdef _LIBC
00434   (void) __fxprintf (NULL, "%s\n", _("memory exhausted"));
00435 # else
00436   fprintf (stderr, "%s\n", _("memory exhausted"));
00437 # endif
00438   exit (obstack_exit_failure);
00439 }
00440 
00441 #endif /* !ELIDE_CODE */