/* 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: This source is derived from an old version taken from the GNU C
+ Library (glibc).
-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., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301,
+ USA. */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
#include "obstack.h"
#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
-#if defined (__STDC__) && __STDC__
#define POINTER void *
-#else
-#define POINTER char *
-#endif
/* Determine default alignment. */
struct fooalign {char 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'. */
+static void print_and_abort (void);
+void (*obstack_alloc_failed_handler) (void) = print_and_abort;
+
+/* 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. */
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)) \
else \
(*(void (*) ()) (h)->freefun) ((old_chunk)); \
} while (0)
+#endif
\f
/* Initialize an obstack H for use. Specify chunk size SIZE (0 means default).
free up some memory, then call this again. */
int
-_obstack_begin (h, size, alignment, chunkfun, freefun)
- struct obstack *h;
- int size;
- int alignment;
- POINTER (*chunkfun) ();
- void (*freefun) ();
+_obstack_begin (struct obstack *h, int size, int alignment,
+ POINTER (*chunkfun) (long), void (*freefun) (void *))
{
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. */
{
size = 4096 - extra;
}
- h->chunkfun = (struct _obstack_chunk * (*)()) chunkfun;
- h->freefun = freefun;
+ h->chunkfun = (struct _obstack_chunk * (*)(void *, long)) chunkfun;
+ h->freefun = (void (*) (void *, struct _obstack_chunk *)) freefun;
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;
}
int
-_obstack_begin_1 (h, size, alignment, chunkfun, freefun, arg)
- struct obstack *h;
- int size;
- int alignment;
- POINTER (*chunkfun) ();
- void (*freefun) ();
- POINTER arg;
+_obstack_begin_1 (struct obstack *h, int size, int alignment,
+ POINTER (*chunkfun) (POINTER, long),
+ void (*freefun) (POINTER, POINTER), 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. */
{
size = 4096 - extra;
}
- h->chunkfun = (struct _obstack_chunk * (*)()) chunkfun;
- h->freefun = freefun;
+ h->chunkfun = (struct _obstack_chunk * (*)(void *,long)) chunkfun;
+ h->freefun = (void (*) (void *, struct _obstack_chunk *)) freefun;
h->chunk_size = size;
h->alignment_mask = alignment - 1;
h->extra_arg = 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;
}
to the beginning of the new one. */
void
-_obstack_newchunk (h, length)
- struct obstack *h;
- int length;
+_obstack_newchunk (struct obstack *h, int 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;
/* 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;
This is here for debugging.
If you use it in a program, you are probably losing. */
-#if defined (__STDC__) && __STDC__
/* Suppress -Wmissing-prototypes warning. We don't want to declare this in
obstack.h because it is just for debugging. */
int _obstack_allocated_p (struct obstack *h, POINTER obj);
-#endif
int
-_obstack_allocated_p (h, obj)
- struct obstack *h;
- POINTER obj;
+_obstack_allocated_p (struct obstack *h, POINTER obj)
{
register struct _obstack_chunk *lp; /* below addr of any objects in this chunk */
register struct _obstack_chunk *plp; /* point to previous chunk if any */
This is the first one, called from non-ANSI code. */
void
-_obstack_free (h, obj)
- struct obstack *h;
- POINTER obj;
+_obstack_free (struct obstack *h, POINTER obj)
{
register struct _obstack_chunk *lp; /* below addr of any objects in this chunk */
register struct _obstack_chunk *plp; /* point to previous chunk if any */
/* This function is used from ANSI code. */
void
-obstack_free (h, obj)
- struct obstack *h;
- POINTER obj;
+obstack_free (struct obstack *h, POINTER obj)
{
register struct _obstack_chunk *lp; /* below addr of any objects in this chunk */
register struct _obstack_chunk *plp; /* point to previous chunk if any */
abort ();
}
\f
+int
+_obstack_memory_used (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 _
+# if (HAVE_LIBINTL_H && ENABLE_NLS) || defined _LIBC
+# include <libintl.h>
+# ifndef _
+# define _(Str) gettext (Str)
+# endif
+# else
+# define _(Str) (Str)
+# endif
+#endif
+
+static void
+print_and_abort (void)
+{
+ 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. */
/* Now define the functional versions of the obstack macros.
Define them to simply use the corresponding macros to do the job. */
-#if defined (__STDC__) && __STDC__
-/* These function definitions do not work with non-ANSI preprocessors;
- they won't pass through the macro names in parentheses. */
-
/* The function names appear in parentheses in order to prevent
the macro-definitions of the names from being expanded there. */
-POINTER (obstack_base) (obstack)
- struct obstack *obstack;
+POINTER (obstack_base) (struct obstack *obstack)
{
return obstack_base (obstack);
}
-POINTER (obstack_next_free) (obstack)
- struct obstack *obstack;
+POINTER (obstack_next_free) (struct obstack *obstack)
{
return obstack_next_free (obstack);
}
-int (obstack_object_size) (obstack)
- struct obstack *obstack;
+int (obstack_object_size) (struct obstack *obstack)
{
return obstack_object_size (obstack);
}
-int (obstack_room) (obstack)
- struct obstack *obstack;
+int (obstack_room) (struct obstack *obstack)
{
return obstack_room (obstack);
}
-void (obstack_grow) (obstack, pointer, length)
- struct obstack *obstack;
- POINTER pointer;
- int length;
+int (obstack_make_room) (struct obstack *obstack, int length)
+{
+ return obstack_make_room (obstack, length);
+}
+
+void (obstack_grow) (struct obstack *obstack, POINTER pointer, int length)
{
obstack_grow (obstack, pointer, length);
}
-void (obstack_grow0) (obstack, pointer, length)
- struct obstack *obstack;
- POINTER pointer;
- int length;
+void (obstack_grow0) (struct obstack *obstack, POINTER pointer, int length)
{
obstack_grow0 (obstack, pointer, length);
}
-void (obstack_1grow) (obstack, character)
- struct obstack *obstack;
- int character;
+void (obstack_1grow) (struct obstack *obstack, int character)
{
obstack_1grow (obstack, character);
}
-void (obstack_blank) (obstack, length)
- struct obstack *obstack;
- int length;
+void (obstack_blank) (struct obstack *obstack, int length)
{
obstack_blank (obstack, length);
}
-void (obstack_1grow_fast) (obstack, character)
- struct obstack *obstack;
- int character;
+void (obstack_1grow_fast) (struct obstack *obstack, int character)
{
obstack_1grow_fast (obstack, character);
}
-void (obstack_blank_fast) (obstack, length)
- struct obstack *obstack;
- int length;
+void (obstack_blank_fast) (struct obstack *obstack, int length)
{
obstack_blank_fast (obstack, length);
}
-POINTER (obstack_finish) (obstack)
- struct obstack *obstack;
+POINTER (obstack_finish) (struct obstack *obstack)
{
return obstack_finish (obstack);
}
-POINTER (obstack_alloc) (obstack, length)
- struct obstack *obstack;
- int length;
+POINTER (obstack_alloc) (struct obstack *obstack, int length)
{
return obstack_alloc (obstack, length);
}
-POINTER (obstack_copy) (obstack, pointer, length)
- struct obstack *obstack;
- POINTER pointer;
- int length;
+POINTER (obstack_copy) (struct obstack *obstack, POINTER pointer, int length)
{
return obstack_copy (obstack, pointer, length);
}
-POINTER (obstack_copy0) (obstack, pointer, length)
- struct obstack *obstack;
- POINTER pointer;
- int length;
+POINTER (obstack_copy0) (struct obstack *obstack, POINTER pointer, int length)
{
return obstack_copy0 (obstack, pointer, length);
}
-#endif /* __STDC__ */
-
#endif /* 0 */
#endif /* !ELIDE_CODE */