summaryrefslogtreecommitdiffstats
path: root/gnu/usr.bin/grep/obstack.c
diff options
context:
space:
mode:
Diffstat (limited to 'gnu/usr.bin/grep/obstack.c')
-rw-r--r--gnu/usr.bin/grep/obstack.c225
1 files changed, 183 insertions, 42 deletions
diff --git a/gnu/usr.bin/grep/obstack.c b/gnu/usr.bin/grep/obstack.c
index 7b9d3b9..c77fdd4 100644
--- a/gnu/usr.bin/grep/obstack.c
+++ b/gnu/usr.bin/grep/obstack.c
@@ -1,5 +1,10 @@
-/* obstack.c - subroutines used implicitly by object stack macros
- Copyright (C) 1988, 1993 Free Software Foundation, Inc.
+/* obstack.h - object stack macros
+ Copyright (C) 1988,89,90,91,92,93,94,96,97, 98 Free Software Foundation, Inc.
+
+ the C library, however. The master source lives in /gd/gnu/lib.
+
+NOTE: The canonical source of this file is maintained with the
+GNU C Library. Bugs can be reported to bug-glibc@prep.ai.mit.edu.
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
@@ -12,26 +17,44 @@ 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, 675 Mass Ave, Cambridge, MA 02139, USA. */
+along with this program; if not, write to the Free Software Foundation,
+Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+/* $FreeBSD$ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
#include "obstack.h"
-/* This is just to get __GNU_LIBRARY__ defined. */
-#include <stdio.h>
+/* NOTE BEFORE MODIFYING THIS FILE: This version number must be
+ incremented whenever callers compiled using an old obstack.h can no
+ longer properly call the functions in this obstack.c. */
+#define OBSTACK_INTERFACE_VERSION 1
/* Comment out all this code if we are using the GNU C Library, and are not
- actually compiling the library itself. This code is part of the GNU C
- Library, but also included in many other GNU distributions. Compiling
+ actually compiling the library itself, and the installed library
+ supports the same library interface we do. This code is part of the GNU
+ C Library, but also included in many other GNU distributions. Compiling
and linking in this code is a waste when using the GNU C library
(especially if it is a shared library). Rather than having every GNU
- program understand `configure --with-gnu-libc' and omit the object files,
- it is simpler to just do this in the source for each such file. */
+ program understand `configure --with-gnu-libc' and omit the object
+ files, it is simpler to just do this in the source for each such file. */
+
+#include <stdio.h> /* Random thing to get __GNU_LIBRARY__. */
+#if !defined (_LIBC) && defined (__GNU_LIBRARY__) && __GNU_LIBRARY__ > 1
+#include <gnu-versions.h>
+#if _GNU_OBSTACK_INTERFACE_VERSION == OBSTACK_INTERFACE_VERSION
+#define ELIDE_CODE
+#endif
+#endif
+
-#if defined (_LIBC) || !defined (__GNU_LIBRARY__)
+#ifndef ELIDE_CODE
-#ifdef __STDC__
+#if defined (__STDC__) && __STDC__
#define POINTER void *
#else
#define POINTER char *
@@ -40,7 +63,7 @@ Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
/* Determine default alignment. */
struct fooalign {char x; double d;};
#define DEFAULT_ALIGNMENT \
- ((PTR_INT_TYPE) ((char *)&((struct fooalign *) 0)->d - (char *)0))
+ ((PTR_INT_TYPE) ((char *) &((struct fooalign *) 0)->d - (char *) 0))
/* If malloc were really smart, it would round addresses to DEFAULT_ALIGNMENT.
But in fact it might be less smart and round addresses to as much as
DEFAULT_ROUNDING. So we prepare for it to do that. */
@@ -55,6 +78,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. */
@@ -66,37 +111,61 @@ 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)) \
- : (*(h)->chunkfun) ((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 \
- (*(h)->freefun) ((old_chunk)); \
+ (*(void (*) (void *)) (h)->freefun) ((old_chunk)); \
} while (0)
+#else
+#define CALL_CHUNKFUN(h, size) \
+ (((h) -> use_extra_arg) \
+ ? (*(h)->chunkfun) ((h)->extra_arg, (size)) \
+ : (*(struct _obstack_chunk *(*) ()) (h)->chunkfun) ((size)))
+
+#define CALL_FREEFUN(h, old_chunk) \
+ do { \
+ if ((h) -> use_extra_arg) \
+ (*(h)->freefun) ((h)->extra_arg, (old_chunk)); \
+ else \
+ (*(void (*) ()) (h)->freefun) ((old_chunk)); \
+ } while (0)
+#endif
/* Initialize an obstack H for use. Specify chunk size SIZE (0 means default).
Objects start on multiples of ALIGNMENT (0 means use default).
CHUNKFUN is the function to use to allocate chunks,
- and FREEFUN the function to free them. */
+ and FREEFUN the function to free them.
-void
+ Return nonzero if successful, zero if out of memory.
+ To recover from an out of memory error,
+ free up some memory, then call this again. */
+
+int
_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 */
+ 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. */
{
@@ -114,34 +183,48 @@ _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)
+ (*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;
}
-void
+int
_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 */
+ 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. */
{
@@ -159,20 +242,29 @@ _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;
h->use_extra_arg = 1;
chunk = h->chunk = CALL_CHUNKFUN (h, h -> chunk_size);
+ if (!chunk)
+ (*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;
}
/* Allocate a new current chunk for the obstack *H
@@ -186,12 +278,12 @@ _obstack_newchunk (h, length)
struct obstack *h;
int length;
{
- register struct _obstack_chunk* old_chunk = h->chunk;
- register struct _obstack_chunk* new_chunk;
+ 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;
@@ -199,7 +291,10 @@ _obstack_newchunk (h, length)
new_size = h->chunk_size;
/* Allocate and initialize the new chunk. */
- new_chunk = h->chunk = CALL_CHUNKFUN (h, new_size);
+ new_chunk = CALL_CHUNKFUN (h, new_size);
+ if (!new_chunk)
+ (*obstack_alloc_failed_handler) ();
+ h->chunk = new_chunk;
new_chunk->prev = old_chunk;
new_chunk->limit = h->chunk_limit = (char *) new_chunk + new_size;
@@ -242,19 +337,25 @@ _obstack_newchunk (h, length)
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;
{
- register struct _obstack_chunk* lp; /* below addr of any objects in this chunk */
- register struct _obstack_chunk* plp; /* point to previous chunk if any */
+ register struct _obstack_chunk *lp; /* below addr of any objects in this chunk */
+ register struct _obstack_chunk *plp; /* point to previous chunk if any */
lp = (h)->chunk;
/* We use >= rather than > since the object cannot be exactly at
the beginning of the chunk but might be an empty object exactly
- at the end of an adjacent chunk. */
- while (lp != 0 && ((POINTER)lp >= obj || (POINTER)(lp)->limit < obj))
+ at the end of an adjacent chunk. */
+ while (lp != 0 && ((POINTER) lp >= obj || (POINTER) (lp)->limit < obj))
{
plp = lp->prev;
lp = plp;
@@ -275,14 +376,14 @@ _obstack_free (h, obj)
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 */
+ register struct _obstack_chunk *lp; /* below addr of any objects in this chunk */
+ register struct _obstack_chunk *plp; /* point to previous chunk if any */
lp = h->chunk;
/* We use >= because there cannot be an object at the beginning of a chunk.
But there can be an empty object at that address
at the end of another chunk. */
- while (lp != 0 && ((POINTER)lp >= obj || (POINTER)(lp)->limit < obj))
+ while (lp != 0 && ((POINTER) lp >= obj || (POINTER) (lp)->limit < obj))
{
plp = lp->prev;
CALL_FREEFUN (h, lp);
@@ -293,7 +394,7 @@ _obstack_free (h, obj)
}
if (lp)
{
- h->object_base = h->next_free = (char *)(obj);
+ h->object_base = h->next_free = (char *) (obj);
h->chunk_limit = lp->limit;
h->chunk = lp;
}
@@ -309,14 +410,14 @@ obstack_free (h, obj)
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 */
+ register struct _obstack_chunk *lp; /* below addr of any objects in this chunk */
+ register struct _obstack_chunk *plp; /* point to previous chunk if any */
lp = h->chunk;
/* We use >= because there cannot be an object at the beginning of a chunk.
But there can be an empty object at that address
at the end of another chunk. */
- while (lp != 0 && ((POINTER)lp >= obj || (POINTER)(lp)->limit < obj))
+ while (lp != 0 && ((POINTER) lp >= obj || (POINTER) (lp)->limit < obj))
{
plp = lp->prev;
CALL_FREEFUN (h, lp);
@@ -327,7 +428,7 @@ obstack_free (h, obj)
}
if (lp)
{
- h->object_base = h->next_free = (char *)(obj);
+ h->object_base = h->next_free = (char *) (obj);
h->chunk_limit = lp->limit;
h->chunk = lp;
}
@@ -336,6 +437,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. */
@@ -343,7 +477,7 @@ obstack_free (h, obj)
/* Now define the functional versions of the obstack macros.
Define them to simply use the corresponding macros to do the job. */
-#ifdef __STDC__
+#if defined (__STDC__) && __STDC__
/* These function definitions do not work with non-ANSI preprocessors;
they won't pass through the macro names in parentheses. */
@@ -374,6 +508,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;
@@ -451,4 +592,4 @@ POINTER (obstack_copy0) (obstack, pointer, length)
#endif /* 0 */
-#endif /* _LIBC or not __GNU_LIBRARY__. */
+#endif /* !ELIDE_CODE */
OpenPOWER on IntegriCloud