diff options
author | Michael Shalayeff <mickey@cvs.openbsd.org> | 2000-03-09 00:08:11 +0000 |
---|---|---|
committer | Michael Shalayeff <mickey@cvs.openbsd.org> | 2000-03-09 00:08:11 +0000 |
commit | 3f5956a6c8278d6b81c9304de4d6c2f09212c8d9 (patch) | |
tree | 9e2000b6473ce3c30201a5a51a096a2728d2239d /gnu/usr.bin/grep/obstack.c | |
parent | 9da93fd65da2073262c1b5085492fbed52beb3b0 (diff) |
new grep 2.4.1
whole bunch of bug fixes, mmap support (w/ --mmap)
changed binary file grep behavior, but could be overwritten w/ -a
millert@ ok
Diffstat (limited to 'gnu/usr.bin/grep/obstack.c')
-rw-r--r-- | gnu/usr.bin/grep/obstack.c | 246 |
1 files changed, 193 insertions, 53 deletions
diff --git a/gnu/usr.bin/grep/obstack.c b/gnu/usr.bin/grep/obstack.c index ebcc6a00993..17c63134315 100644 --- a/gnu/usr.bin/grep/obstack.c +++ b/gnu/usr.bin/grep/obstack.c @@ -1,41 +1,57 @@ /* obstack.c - subroutines used implicitly by object stack macros - Copyright (C) 1988, 1993 Free Software Foundation, Inc. + Copyright (C) 1988-1994,96,97,98,99 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 file is part of the GNU C Library. Its master source is NOT part of + the C library, however. The master source lives in /gd/gnu/lib. -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. + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. -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. */ + The GNU C Library 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 + Library General Public License for more details. -#ifndef lint -static char rcsid[] = "$Id: obstack.c,v 1.1 1995/10/18 08:40:17 deraadt Exp $"; -#endif /* not lint */ + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. 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" -/* 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 * @@ -44,7 +60,7 @@ static char rcsid[] = "$Id: obstack.c,v 1.1 1995/10/18 08:40:17 deraadt Exp $"; /* 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. */ @@ -59,6 +75,30 @@ 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 can be set to a user defined function which should either + abort gracefully or use longjump - but shouldn't return. 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. */ @@ -70,37 +110,60 @@ 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, calls obstack_alloc_failed_handler if + allocation fails. */ + +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. */ { @@ -118,34 +181,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. */ { @@ -163,20 +240,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 @@ -190,12 +276,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; @@ -203,7 +289,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; @@ -246,19 +335,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; @@ -279,14 +374,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); @@ -297,7 +392,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; } @@ -313,14 +408,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); @@ -331,7 +426,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; } @@ -340,6 +435,44 @@ 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 +#if defined _LIBC && defined USE_IN_LIBIO +# include <libio/iolibio.h> +# define fputs(s, f) _IO_fputs (s, f) +#endif + +static void +print_and_abort () +{ + fputs (_("memory exhausted"), stderr); + fputc ('\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. */ @@ -347,7 +480,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. */ @@ -378,6 +511,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; @@ -455,4 +595,4 @@ POINTER (obstack_copy0) (obstack, pointer, length) #endif /* 0 */ -#endif /* _LIBC or not __GNU_LIBRARY__. */ +#endif /* !ELIDE_CODE */ |