]> git.ipfire.org Git - thirdparty/gcc.git/blobdiff - libiberty/obstack.c
pexecute.c: Updates from gcc.
[thirdparty/gcc.git] / libiberty / obstack.c
index a6880caaa6cebc33721a5c8d80272963cd91d4dc..bc318b37790eeb1cde7bdcde56fe383c60a9a310 100644 (file)
@@ -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
 
 \f
 /* 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 ();
 }
 \f
+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;
+}
+\f
+/* 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);
+}
+\f
 #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;