Back to index

cell-binutils  2.17cvs20070401
obstack.c
Go to the documentation of this file.
00001 /* obstack.c - subroutines used implicitly by object stack macros
00002    Copyright (C) 1988,89,90,91,92,93,94,96,97 Free Software Foundation, Inc.
00003 
00004 
00005    NOTE: This source is derived from an old version taken from the GNU C
00006    Library (glibc).
00007 
00008    This program is free software; you can redistribute it and/or modify it
00009    under the terms of the GNU General Public License as published by the
00010    Free Software Foundation; either version 2, or (at your option) any
00011    later version.
00012 
00013    This program is distributed in the hope that it will be useful,
00014    but WITHOUT ANY WARRANTY; without even the implied warranty of
00015    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00016    GNU General Public License for more details.
00017 
00018    You should have received a copy of the GNU General Public License
00019    along with this program; if not, write to the Free Software
00020    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301,
00021    USA.  */
00022 
00023 #ifdef HAVE_CONFIG_H
00024 #include <config.h>
00025 #endif
00026 
00027 #include "obstack.h"
00028 
00029 /* NOTE BEFORE MODIFYING THIS FILE: This version number must be
00030    incremented whenever callers compiled using an old obstack.h can no
00031    longer properly call the functions in this obstack.c.  */
00032 #define OBSTACK_INTERFACE_VERSION 1
00033 
00034 /* Comment out all this code if we are using the GNU C Library, and are not
00035    actually compiling the library itself, and the installed library
00036    supports the same library interface we do.  This code is part of the GNU
00037    C Library, but also included in many other GNU distributions.  Compiling
00038    and linking in this code is a waste when using the GNU C library
00039    (especially if it is a shared library).  Rather than having every GNU
00040    program understand `configure --with-gnu-libc' and omit the object
00041    files, it is simpler to just do this in the source for each such file.  */
00042 
00043 #include <stdio.h>          /* Random thing to get __GNU_LIBRARY__.  */
00044 #if !defined (_LIBC) && defined (__GNU_LIBRARY__) && __GNU_LIBRARY__ > 1
00045 #include <gnu-versions.h>
00046 #if _GNU_OBSTACK_INTERFACE_VERSION == OBSTACK_INTERFACE_VERSION
00047 #define ELIDE_CODE
00048 #endif
00049 #endif
00050 
00051 
00052 #ifndef ELIDE_CODE
00053 
00054 
00055 #define POINTER void *
00056 
00057 /* Determine default alignment.  */
00058 struct fooalign {char x; double d;};
00059 #define DEFAULT_ALIGNMENT  \
00060   ((PTR_INT_TYPE) ((char *) &((struct fooalign *) 0)->d - (char *) 0))
00061 /* If malloc were really smart, it would round addresses to DEFAULT_ALIGNMENT.
00062    But in fact it might be less smart and round addresses to as much as
00063    DEFAULT_ROUNDING.  So we prepare for it to do that.  */
00064 union fooround {long x; double d;};
00065 #define DEFAULT_ROUNDING (sizeof (union fooround))
00066 
00067 /* When we copy a long block of data, this is the unit to do it with.
00068    On some machines, copying successive ints does not work;
00069    in such a case, redefine COPYING_UNIT to `long' (if that works)
00070    or `char' as a last resort.  */
00071 #ifndef COPYING_UNIT
00072 #define COPYING_UNIT int
00073 #endif
00074 
00075 
00076 /* The functions allocating more room by calling `obstack_chunk_alloc'
00077    jump to the handler pointed to by `obstack_alloc_failed_handler'.
00078    This variable by default points to the internal function
00079    `print_and_abort'.  */
00080 static void print_and_abort (void);
00081 void (*obstack_alloc_failed_handler) (void) = print_and_abort;
00082 
00083 /* Exit value used when `print_and_abort' is used.  */
00084 #if defined __GNU_LIBRARY__ || defined HAVE_STDLIB_H
00085 #include <stdlib.h>
00086 #endif
00087 #ifndef EXIT_FAILURE
00088 #define EXIT_FAILURE 1
00089 #endif
00090 int obstack_exit_failure = EXIT_FAILURE;
00091 
00092 /* The non-GNU-C macros copy the obstack into this global variable
00093    to avoid multiple evaluation.  */
00094 
00095 struct obstack *_obstack;
00096 
00097 /* Define a macro that either calls functions with the traditional malloc/free
00098    calling interface, or calls functions with the mmalloc/mfree interface
00099    (that adds an extra first argument), based on the state of use_extra_arg.
00100    For free, do not use ?:, since some compilers, like the MIPS compilers,
00101    do not allow (expr) ? void : void.  */
00102 
00103 #if defined (__STDC__) && __STDC__
00104 #define CALL_CHUNKFUN(h, size) \
00105   (((h) -> use_extra_arg) \
00106    ? (*(h)->chunkfun) ((h)->extra_arg, (size)) \
00107    : (*(struct _obstack_chunk *(*) (long)) (h)->chunkfun) ((size)))
00108 
00109 #define CALL_FREEFUN(h, old_chunk) \
00110   do { \
00111     if ((h) -> use_extra_arg) \
00112       (*(h)->freefun) ((h)->extra_arg, (old_chunk)); \
00113     else \
00114       (*(void (*) (void *)) (h)->freefun) ((old_chunk)); \
00115   } while (0)
00116 #else
00117 #define CALL_CHUNKFUN(h, size) \
00118   (((h) -> use_extra_arg) \
00119    ? (*(h)->chunkfun) ((h)->extra_arg, (size)) \
00120    : (*(struct _obstack_chunk *(*) ()) (h)->chunkfun) ((size)))
00121 
00122 #define CALL_FREEFUN(h, old_chunk) \
00123   do { \
00124     if ((h) -> use_extra_arg) \
00125       (*(h)->freefun) ((h)->extra_arg, (old_chunk)); \
00126     else \
00127       (*(void (*) ()) (h)->freefun) ((old_chunk)); \
00128   } while (0)
00129 #endif
00130 
00131 
00132 /* Initialize an obstack H for use.  Specify chunk size SIZE (0 means default).
00133    Objects start on multiples of ALIGNMENT (0 means use default).
00134    CHUNKFUN is the function to use to allocate chunks,
00135    and FREEFUN the function to free them.
00136 
00137    Return nonzero if successful, zero if out of memory.
00138    To recover from an out of memory error,
00139    free up some memory, then call this again.  */
00140 
00141 int
00142 _obstack_begin (struct obstack *h, int size, int alignment,
00143                 POINTER (*chunkfun) (long), void (*freefun) (void *))
00144 {
00145   register struct _obstack_chunk *chunk; /* points to new chunk */
00146 
00147   if (alignment == 0)
00148     alignment = (int) DEFAULT_ALIGNMENT;
00149   if (size == 0)
00150     /* Default size is what GNU malloc can fit in a 4096-byte block.  */
00151     {
00152       /* 12 is sizeof (mhead) and 4 is EXTRA from GNU malloc.
00153         Use the values for range checking, because if range checking is off,
00154         the extra bytes won't be missed terribly, but if range checking is on
00155         and we used a larger request, a whole extra 4096 bytes would be
00156         allocated.
00157 
00158         These number are irrelevant to the new GNU malloc.  I suspect it is
00159         less sensitive to the size of the request.  */
00160       int extra = ((((12 + DEFAULT_ROUNDING - 1) & ~(DEFAULT_ROUNDING - 1))
00161                   + 4 + DEFAULT_ROUNDING - 1)
00162                  & ~(DEFAULT_ROUNDING - 1));
00163       size = 4096 - extra;
00164     }
00165 
00166   h->chunkfun = (struct _obstack_chunk * (*)(void *, long)) chunkfun;
00167   h->freefun = (void (*) (void *, struct _obstack_chunk *)) freefun;
00168   h->chunk_size = size;
00169   h->alignment_mask = alignment - 1;
00170   h->use_extra_arg = 0;
00171 
00172   chunk = h->chunk = CALL_CHUNKFUN (h, h -> chunk_size);
00173   if (!chunk)
00174     (*obstack_alloc_failed_handler) ();
00175   h->next_free = h->object_base = chunk->contents;
00176   h->chunk_limit = chunk->limit
00177     = (char *) chunk + h->chunk_size;
00178   chunk->prev = 0;
00179   /* The initial chunk now contains no empty object.  */
00180   h->maybe_empty_object = 0;
00181   h->alloc_failed = 0;
00182   return 1;
00183 }
00184 
00185 int
00186 _obstack_begin_1 (struct obstack *h, int size, int alignment,
00187                   POINTER (*chunkfun) (POINTER, long),
00188                   void (*freefun) (POINTER, POINTER), POINTER arg)
00189 {
00190   register struct _obstack_chunk *chunk; /* points to new chunk */
00191 
00192   if (alignment == 0)
00193     alignment = (int) DEFAULT_ALIGNMENT;
00194   if (size == 0)
00195     /* Default size is what GNU malloc can fit in a 4096-byte block.  */
00196     {
00197       /* 12 is sizeof (mhead) and 4 is EXTRA from GNU malloc.
00198         Use the values for range checking, because if range checking is off,
00199         the extra bytes won't be missed terribly, but if range checking is on
00200         and we used a larger request, a whole extra 4096 bytes would be
00201         allocated.
00202 
00203         These number are irrelevant to the new GNU malloc.  I suspect it is
00204         less sensitive to the size of the request.  */
00205       int extra = ((((12 + DEFAULT_ROUNDING - 1) & ~(DEFAULT_ROUNDING - 1))
00206                   + 4 + DEFAULT_ROUNDING - 1)
00207                  & ~(DEFAULT_ROUNDING - 1));
00208       size = 4096 - extra;
00209     }
00210 
00211   h->chunkfun = (struct _obstack_chunk * (*)(void *,long)) chunkfun;
00212   h->freefun = (void (*) (void *, struct _obstack_chunk *)) freefun;
00213   h->chunk_size = size;
00214   h->alignment_mask = alignment - 1;
00215   h->extra_arg = arg;
00216   h->use_extra_arg = 1;
00217 
00218   chunk = h->chunk = CALL_CHUNKFUN (h, h -> chunk_size);
00219   if (!chunk)
00220     (*obstack_alloc_failed_handler) ();
00221   h->next_free = h->object_base = chunk->contents;
00222   h->chunk_limit = chunk->limit
00223     = (char *) chunk + h->chunk_size;
00224   chunk->prev = 0;
00225   /* The initial chunk now contains no empty object.  */
00226   h->maybe_empty_object = 0;
00227   h->alloc_failed = 0;
00228   return 1;
00229 }
00230 
00231 /* Allocate a new current chunk for the obstack *H
00232    on the assumption that LENGTH bytes need to be added
00233    to the current object, or a new object of length LENGTH allocated.
00234    Copies any partial object from the end of the old chunk
00235    to the beginning of the new one.  */
00236 
00237 void
00238 _obstack_newchunk (struct obstack *h, int length)
00239 {
00240   register struct _obstack_chunk *old_chunk = h->chunk;
00241   register struct _obstack_chunk *new_chunk;
00242   register long      new_size;
00243   register long obj_size = h->next_free - h->object_base;
00244   register long i;
00245   long already;
00246 
00247   /* Compute size for new chunk.  */
00248   new_size = (obj_size + length) + (obj_size >> 3) + 100;
00249   if (new_size < h->chunk_size)
00250     new_size = h->chunk_size;
00251 
00252   /* Allocate and initialize the new chunk.  */
00253   new_chunk = CALL_CHUNKFUN (h, new_size);
00254   if (!new_chunk)
00255     (*obstack_alloc_failed_handler) ();
00256   h->chunk = new_chunk;
00257   new_chunk->prev = old_chunk;
00258   new_chunk->limit = h->chunk_limit = (char *) new_chunk + new_size;
00259 
00260   /* Move the existing object to the new chunk.
00261      Word at a time is fast and is safe if the object
00262      is sufficiently aligned.  */
00263   if (h->alignment_mask + 1 >= DEFAULT_ALIGNMENT)
00264     {
00265       for (i = obj_size / sizeof (COPYING_UNIT) - 1;
00266           i >= 0; i--)
00267        ((COPYING_UNIT *)new_chunk->contents)[i]
00268          = ((COPYING_UNIT *)h->object_base)[i];
00269       /* We used to copy the odd few remaining bytes as one extra COPYING_UNIT,
00270         but that can cross a page boundary on a machine
00271         which does not do strict alignment for COPYING_UNITS.  */
00272       already = obj_size / sizeof (COPYING_UNIT) * sizeof (COPYING_UNIT);
00273     }
00274   else
00275     already = 0;
00276   /* Copy remaining bytes one by one.  */
00277   for (i = already; i < obj_size; i++)
00278     new_chunk->contents[i] = h->object_base[i];
00279 
00280   /* If the object just copied was the only data in OLD_CHUNK,
00281      free that chunk and remove it from the chain.
00282      But not if that chunk might contain an empty object.  */
00283   if (h->object_base == old_chunk->contents && ! h->maybe_empty_object)
00284     {
00285       new_chunk->prev = old_chunk->prev;
00286       CALL_FREEFUN (h, old_chunk);
00287     }
00288 
00289   h->object_base = new_chunk->contents;
00290   h->next_free = h->object_base + obj_size;
00291   /* The new chunk certainly contains no empty object yet.  */
00292   h->maybe_empty_object = 0;
00293 }
00294 
00295 /* Return nonzero if object OBJ has been allocated from obstack H.
00296    This is here for debugging.
00297    If you use it in a program, you are probably losing.  */
00298 
00299 /* Suppress -Wmissing-prototypes warning.  We don't want to declare this in
00300    obstack.h because it is just for debugging.  */
00301 int _obstack_allocated_p (struct obstack *h, POINTER obj);
00302 
00303 int
00304 _obstack_allocated_p (struct obstack *h, POINTER obj)
00305 {
00306   register struct _obstack_chunk *lp;     /* below addr of any objects in this chunk */
00307   register struct _obstack_chunk *plp;    /* point to previous chunk if any */
00308 
00309   lp = (h)->chunk;
00310   /* We use >= rather than > since the object cannot be exactly at
00311      the beginning of the chunk but might be an empty object exactly
00312      at the end of an adjacent chunk.  */
00313   while (lp != 0 && ((POINTER) lp >= obj || (POINTER) (lp)->limit < obj))
00314     {
00315       plp = lp->prev;
00316       lp = plp;
00317     }
00318   return lp != 0;
00319 }
00320 
00321 /* Free objects in obstack H, including OBJ and everything allocate
00322    more recently than OBJ.  If OBJ is zero, free everything in H.  */
00323 
00324 #undef obstack_free
00325 
00326 /* This function has two names with identical definitions.
00327    This is the first one, called from non-ANSI code.  */
00328 
00329 void
00330 _obstack_free (struct obstack *h, POINTER obj)
00331 {
00332   register struct _obstack_chunk *lp;     /* below addr of any objects in this chunk */
00333   register struct _obstack_chunk *plp;    /* point to previous chunk if any */
00334 
00335   lp = h->chunk;
00336   /* We use >= because there cannot be an object at the beginning of a chunk.
00337      But there can be an empty object at that address
00338      at the end of another chunk.  */
00339   while (lp != 0 && ((POINTER) lp >= obj || (POINTER) (lp)->limit < obj))
00340     {
00341       plp = lp->prev;
00342       CALL_FREEFUN (h, lp);
00343       lp = plp;
00344       /* If we switch chunks, we can't tell whether the new current
00345         chunk contains an empty object, so assume that it may.  */
00346       h->maybe_empty_object = 1;
00347     }
00348   if (lp)
00349     {
00350       h->object_base = h->next_free = (char *) (obj);
00351       h->chunk_limit = lp->limit;
00352       h->chunk = lp;
00353     }
00354   else if (obj != 0)
00355     /* obj is not in any of the chunks! */
00356     abort ();
00357 }
00358 
00359 /* This function is used from ANSI code.  */
00360 
00361 void
00362 obstack_free (struct obstack *h, POINTER obj)
00363 {
00364   register struct _obstack_chunk *lp;     /* below addr of any objects in this chunk */
00365   register struct _obstack_chunk *plp;    /* point to previous chunk if any */
00366 
00367   lp = h->chunk;
00368   /* We use >= because there cannot be an object at the beginning of a chunk.
00369      But there can be an empty object at that address
00370      at the end of another chunk.  */
00371   while (lp != 0 && ((POINTER) lp >= obj || (POINTER) (lp)->limit < obj))
00372     {
00373       plp = lp->prev;
00374       CALL_FREEFUN (h, lp);
00375       lp = plp;
00376       /* If we switch chunks, we can't tell whether the new current
00377         chunk contains an empty object, so assume that it may.  */
00378       h->maybe_empty_object = 1;
00379     }
00380   if (lp)
00381     {
00382       h->object_base = h->next_free = (char *) (obj);
00383       h->chunk_limit = lp->limit;
00384       h->chunk = lp;
00385     }
00386   else if (obj != 0)
00387     /* obj is not in any of the chunks! */
00388     abort ();
00389 }
00390 
00391 int
00392 _obstack_memory_used (struct obstack *h)
00393 {
00394   register struct _obstack_chunk* lp;
00395   register int nbytes = 0;
00396 
00397   for (lp = h->chunk; lp != 0; lp = lp->prev)
00398     {
00399       nbytes += lp->limit - (char *) lp;
00400     }
00401   return nbytes;
00402 }
00403 
00404 /* Define the error handler.  */
00405 #ifndef _
00406 # if (HAVE_LIBINTL_H && ENABLE_NLS) || defined _LIBC
00407 #  include <libintl.h>
00408 #  ifndef _
00409 #   define _(Str) gettext (Str)
00410 #  endif
00411 # else
00412 #  define _(Str) (Str)
00413 # endif
00414 #endif
00415 
00416 static void
00417 print_and_abort (void)
00418 {
00419   fputs (_("memory exhausted\n"), stderr);
00420   exit (obstack_exit_failure);
00421 }
00422 
00423 #if 0
00424 /* These are now turned off because the applications do not use it
00425    and it uses bcopy via obstack_grow, which causes trouble on sysV.  */
00426 
00427 /* Now define the functional versions of the obstack macros.
00428    Define them to simply use the corresponding macros to do the job.  */
00429 
00430 /* The function names appear in parentheses in order to prevent
00431    the macro-definitions of the names from being expanded there.  */
00432 
00433 POINTER (obstack_base) (struct obstack *obstack)
00434 {
00435   return obstack_base (obstack);
00436 }
00437 
00438 POINTER (obstack_next_free) (struct obstack *obstack)
00439 {
00440   return obstack_next_free (obstack);
00441 }
00442 
00443 int (obstack_object_size) (struct obstack *obstack)
00444 {
00445   return obstack_object_size (obstack);
00446 }
00447 
00448 int (obstack_room) (struct obstack *obstack)
00449 {
00450   return obstack_room (obstack);
00451 }
00452 
00453 int (obstack_make_room) (struct obstack *obstack, int length)
00454 {
00455   return obstack_make_room (obstack, length);
00456 }
00457 
00458 void (obstack_grow) (struct obstack *obstack, POINTER pointer, int length)
00459 {
00460   obstack_grow (obstack, pointer, length);
00461 }
00462 
00463 void (obstack_grow0) (struct obstack *obstack, POINTER pointer, int length)
00464 {
00465   obstack_grow0 (obstack, pointer, length);
00466 }
00467 
00468 void (obstack_1grow) (struct obstack *obstack, int character)
00469 {
00470   obstack_1grow (obstack, character);
00471 }
00472 
00473 void (obstack_blank) (struct obstack *obstack, int length)
00474 {
00475   obstack_blank (obstack, length);
00476 }
00477 
00478 void (obstack_1grow_fast) (struct obstack *obstack, int character)
00479 {
00480   obstack_1grow_fast (obstack, character);
00481 }
00482 
00483 void (obstack_blank_fast) (struct obstack *obstack, int length)
00484 {
00485   obstack_blank_fast (obstack, length);
00486 }
00487 
00488 POINTER (obstack_finish) (struct obstack *obstack)
00489 {
00490   return obstack_finish (obstack);
00491 }
00492 
00493 POINTER (obstack_alloc) (struct obstack *obstack, int length)
00494 {
00495   return obstack_alloc (obstack, length);
00496 }
00497 
00498 POINTER (obstack_copy) (struct obstack *obstack, POINTER pointer, int length)
00499 {
00500   return obstack_copy (obstack, pointer, length);
00501 }
00502 
00503 POINTER (obstack_copy0) (struct obstack *obstack, POINTER pointer, int length)
00504 {
00505   return obstack_copy0 (obstack, pointer, length);
00506 }
00507 
00508 #endif /* 0 */
00509 
00510 #endif /* !ELIDE_CODE */