diff options
-rw-r--r-- | libiberty/ChangeLog | 2 | ||||
-rw-r--r-- | libiberty/obstack.c | 177 |
2 files changed, 129 insertions, 50 deletions
diff --git a/libiberty/ChangeLog b/libiberty/ChangeLog index 9399d6e..6da7194 100644 --- a/libiberty/ChangeLog +++ b/libiberty/ChangeLog @@ -3,7 +3,7 @@ Sat Sep 5 03:24:49 1998 Jeffrey A Law (law@cygnus.com) * pexecute.c: Updates from gcc. Copy in gcc has been removed. This is the canonical copy. Define ISSPACE if !IN_GCC. * alloca.c, vfprintf.c, choose-temp.c, mkstemp.c, getopt.c: Similarly. - * getopt1.c: Similarly. + * getopt1.c, obstack.c: Similarly. * Makefile.in: Build mkstemp.o Wed Aug 19 14:05:01 1998 Mumit Khan <khan@xraylith.wisc.edu> diff --git a/libiberty/obstack.c b/libiberty/obstack.c index a6880ca..bc318b3 100644 --- a/libiberty/obstack.c +++ b/libiberty/obstack.c @@ -1,19 +1,28 @@ /* obstack.c - subroutines used implicitly by object stack macros - Copyright (C) 1988, 89, 90, 91, 92, 93, 94, 95, 96 Free Software Foundation, Inc. + Copyright (C) 1988,89,90,91,92,93,94,96,97 Free Software Foundation, Inc. -This program is free software; you can redistribute it and/or modify it -under the terms of the GNU General Public License as published by the -Free Software Foundation; either version 2, or (at your option) any -later version. -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. + NOTE: The canonical source of this file is maintained with the GNU C Library. + Bugs can be reported to bug-glibc@gnu.org. -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ + This program is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by the + Free Software Foundation; either version 2, or (at your option) any + later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + USA. */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif #include "obstack.h" @@ -39,23 +48,6 @@ Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ #endif #endif -/* CYGNUS LOCAL (not to be elided!) */ - -int -_obstack_memory_used (h) - struct obstack *h; -{ - register struct _obstack_chunk* lp; - register int nbytes = 0; - - for (lp = h->chunk; lp != 0; lp = lp->prev) - { - nbytes += lp->limit - (char *) lp; - } - return nbytes; -} - -/* END CYGNUS LOCAL */ #ifndef ELIDE_CODE @@ -84,6 +76,28 @@ union fooround {long x; double d;}; #define COPYING_UNIT int #endif + +/* The functions allocating more room by calling `obstack_chunk_alloc' + jump to the handler pointed to by `obstack_alloc_failed_handler'. + This variable by default points to the internal function + `print_and_abort'. */ +#if defined (__STDC__) && __STDC__ +static void print_and_abort (void); +void (*obstack_alloc_failed_handler) (void) = print_and_abort; +#else +static void print_and_abort (); +void (*obstack_alloc_failed_handler) () = print_and_abort; +#endif + +/* Exit value used when `print_and_abort' is used. */ +#if defined __GNU_LIBRARY__ || defined HAVE_STDLIB_H +#include <stdlib.h> +#endif +#ifndef EXIT_FAILURE +#define EXIT_FAILURE 1 +#endif +int obstack_exit_failure = EXIT_FAILURE; + /* The non-GNU-C macros copy the obstack into this global variable to avoid multiple evaluation. */ @@ -95,6 +109,20 @@ struct obstack *_obstack; For free, do not use ?:, since some compilers, like the MIPS compilers, do not allow (expr) ? void : void. */ +#if defined (__STDC__) && __STDC__ +#define CALL_CHUNKFUN(h, size) \ + (((h) -> use_extra_arg) \ + ? (*(h)->chunkfun) ((h)->extra_arg, (size)) \ + : (*(struct _obstack_chunk *(*) (long)) (h)->chunkfun) ((size))) + +#define CALL_FREEFUN(h, old_chunk) \ + do { \ + if ((h) -> use_extra_arg) \ + (*(h)->freefun) ((h)->extra_arg, (old_chunk)); \ + else \ + (*(void (*) (void *)) (h)->freefun) ((old_chunk)); \ + } while (0) +#else #define CALL_CHUNKFUN(h, size) \ (((h) -> use_extra_arg) \ ? (*(h)->chunkfun) ((h)->extra_arg, (size)) \ @@ -107,6 +135,7 @@ struct obstack *_obstack; else \ (*(void (*) ()) (h)->freefun) ((old_chunk)); \ } while (0) +#endif /* Initialize an obstack H for use. Specify chunk size SIZE (0 means default). @@ -123,13 +152,18 @@ _obstack_begin (h, size, alignment, chunkfun, freefun) struct obstack *h; int size; int alignment; +#if defined (__STDC__) && __STDC__ + POINTER (*chunkfun) (long); + void (*freefun) (void *); +#else POINTER (*chunkfun) (); void (*freefun) (); +#endif { register struct _obstack_chunk *chunk; /* points to new chunk */ if (alignment == 0) - alignment = DEFAULT_ALIGNMENT; + alignment = (int) DEFAULT_ALIGNMENT; if (size == 0) /* Default size is what GNU malloc can fit in a 4096-byte block. */ { @@ -147,25 +181,27 @@ _obstack_begin (h, size, alignment, chunkfun, freefun) size = 4096 - extra; } +#if defined (__STDC__) && __STDC__ + h->chunkfun = (struct _obstack_chunk * (*)(void *, long)) chunkfun; + h->freefun = (void (*) (void *, struct _obstack_chunk *)) freefun; +#else h->chunkfun = (struct _obstack_chunk * (*)()) chunkfun; h->freefun = freefun; +#endif h->chunk_size = size; h->alignment_mask = alignment - 1; h->use_extra_arg = 0; chunk = h->chunk = CALL_CHUNKFUN (h, h -> chunk_size); if (!chunk) - { - h->alloc_failed = 1; - return 0; - } - h->alloc_failed = 0; + (*obstack_alloc_failed_handler) (); h->next_free = h->object_base = chunk->contents; h->chunk_limit = chunk->limit = (char *) chunk + h->chunk_size; chunk->prev = 0; /* The initial chunk now contains no empty object. */ h->maybe_empty_object = 0; + h->alloc_failed = 0; return 1; } @@ -174,14 +210,19 @@ _obstack_begin_1 (h, size, alignment, chunkfun, freefun, arg) struct obstack *h; int size; int alignment; +#if defined (__STDC__) && __STDC__ + POINTER (*chunkfun) (POINTER, long); + void (*freefun) (POINTER, POINTER); +#else POINTER (*chunkfun) (); void (*freefun) (); +#endif POINTER arg; { register struct _obstack_chunk *chunk; /* points to new chunk */ if (alignment == 0) - alignment = DEFAULT_ALIGNMENT; + alignment = (int) DEFAULT_ALIGNMENT; if (size == 0) /* Default size is what GNU malloc can fit in a 4096-byte block. */ { @@ -199,8 +240,13 @@ _obstack_begin_1 (h, size, alignment, chunkfun, freefun, arg) size = 4096 - extra; } +#if defined(__STDC__) && __STDC__ + h->chunkfun = (struct _obstack_chunk * (*)(void *,long)) chunkfun; + h->freefun = (void (*) (void *, struct _obstack_chunk *)) freefun; +#else h->chunkfun = (struct _obstack_chunk * (*)()) chunkfun; h->freefun = freefun; +#endif h->chunk_size = size; h->alignment_mask = alignment - 1; h->extra_arg = arg; @@ -208,17 +254,14 @@ _obstack_begin_1 (h, size, alignment, chunkfun, freefun, arg) chunk = h->chunk = CALL_CHUNKFUN (h, h -> chunk_size); if (!chunk) - { - h->alloc_failed = 1; - return 0; - } - h->alloc_failed = 0; + (*obstack_alloc_failed_handler) (); h->next_free = h->object_base = chunk->contents; h->chunk_limit = chunk->limit = (char *) chunk + h->chunk_size; chunk->prev = 0; /* The initial chunk now contains no empty object. */ h->maybe_empty_object = 0; + h->alloc_failed = 0; return 1; } @@ -236,9 +279,9 @@ _obstack_newchunk (h, length) register struct _obstack_chunk *old_chunk = h->chunk; register struct _obstack_chunk *new_chunk; register long new_size; - register int obj_size = h->next_free - h->object_base; - register int i; - int already; + register long obj_size = h->next_free - h->object_base; + register long i; + long already; /* Compute size for new chunk. */ new_size = (obj_size + length) + (obj_size >> 3) + 100; @@ -248,11 +291,7 @@ _obstack_newchunk (h, length) /* Allocate and initialize the new chunk. */ new_chunk = CALL_CHUNKFUN (h, new_size); if (!new_chunk) - { - h->alloc_failed = 1; - return; - } - h->alloc_failed = 0; + (*obstack_alloc_failed_handler) (); h->chunk = new_chunk; new_chunk->prev = old_chunk; new_chunk->limit = h->chunk_limit = (char *) new_chunk + new_size; @@ -396,6 +435,39 @@ obstack_free (h, obj) abort (); } +int +_obstack_memory_used (h) + struct obstack *h; +{ + register struct _obstack_chunk* lp; + register int nbytes = 0; + + for (lp = h->chunk; lp != 0; lp = lp->prev) + { + nbytes += lp->limit - (char *) lp; + } + return nbytes; +} + +/* Define the error handler. */ +#ifndef _ +# ifdef HAVE_LIBINTL_H +# include <libintl.h> +# ifndef _ +# define _(Str) gettext (Str) +# endif +# else +# define _(Str) (Str) +# endif +#endif + +static void +print_and_abort () +{ + fputs (_("memory exhausted\n"), stderr); + exit (obstack_exit_failure); +} + #if 0 /* These are now turned off because the applications do not use it and it uses bcopy via obstack_grow, which causes trouble on sysV. */ @@ -434,6 +506,13 @@ int (obstack_room) (obstack) return obstack_room (obstack); } +int (obstack_make_room) (obstack, length) + struct obstack *obstack; + int length; +{ + return obstack_make_room (obstack, length); +} + void (obstack_grow) (obstack, pointer, length) struct obstack *obstack; POINTER pointer; |