diff --git a/.gitignore b/.gitignore index 528fe32..0aa0e24 100644 --- a/.gitignore +++ b/.gitignore @@ -5,9 +5,13 @@ Makefile aclocal.m4 autom4te.cache/ compile +config.guess config.log config.status +config.sub configure depcomp +ltmain.sh install-sh missing +m4/ diff --git a/COPYING b/COPYING index e811ef5..3403f14 100644 --- a/COPYING +++ b/COPYING @@ -1,18 +1,22 @@ - Copyright (C) 1988-1994,1996-1999,2003,2004,2005,2009,2011 - Free Software Foundation, Inc. - This file is part of the GNU C Library. + Copyright 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1996, 1997, 1998, + 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2008 + Free Software Foundation, Inc. - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - The GNU C Library is distributed in the hope that it will be useful, + NOTE: The canonical source of this file is maintained with the GNU C Library. + Bugs can be reported to bug-glibc@gnu.org. + + 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 - Lesser General Public License for more details. + 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 Lesser General Public - License along with the GNU C Library; if not, write to the Free - Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. + 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. diff --git a/Makefile.am b/Makefile.am index 4be132e..6bb5c47 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,5 +1,6 @@ ## Makefile.am - procress this file with automake to produce Makefile.in -lib_LIBRARIES = libobstack.a -libobstack_a_SOURCES = obstack.c -libobstack_a_HEADERS = obstack.h -libobstack_adir = $(includedir) +lib_LTLIBRARIES = libobstack.la +libobstack_la_SOURCES = obstack.c +libobstack_la_HEADERS = obstack.h +libobstack_ladir = $(includedir) +ACLOCAL_AMFLAGS = -Im4 diff --git a/bootstrap.sh b/bootstrap.sh index 9e026b5..cd4a585 100755 --- a/bootstrap.sh +++ b/bootstrap.sh @@ -1,4 +1,5 @@ #!/bin/sh +libtoolize aclocal autoconf automake --add-missing diff --git a/configure.ac b/configure.ac index 96daf50..86ae97e 100644 --- a/configure.ac +++ b/configure.ac @@ -2,12 +2,13 @@ dnl Process this file with autoconf to produce a configure script AC_PREREQ(2.69) -AC_INIT([obstack], [1.0], [Jürgen Buchmüller ]) +AC_INIT([obstack], [1.0], [pullmoll@t-online.de]) AM_INIT_AUTOMAKE([1.15]) +AC_CONFIG_MACRO_DIR([m4]) AC_PROG_CC -AC_PROG_RANLIB +AC_PROG_LIBTOOL AC_CHECK_HEADERS(stddef.h stdio.h stdint.h inttypes.h) diff --git a/obstack.c b/obstack.c index db2cecf..a6dbaf0 100644 --- a/obstack.c +++ b/obstack.c @@ -1,34 +1,30 @@ /* obstack.c - subroutines used implicitly by object stack macros - Copyright (C) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1996, 1997, 1998, - 1999, 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. - This file is part of the GNU C Library. + Copyright (C) 1988,89,90,91,92,93,94,96,97 Free Software Foundation, Inc. - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - The GNU C Library is distributed in the hope that it will be useful, + NOTE: This source is derived from an old version taken from the GNU C + Library (glibc). + + 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, write to the Free - Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. */ + 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 +#include #endif -#ifdef _LIBC -# include -# include -#else -# include "obstack.h" -#endif +#include "obstack.h" /* NOTE BEFORE MODIFYING THIS FILE: This version number must be incremented whenever callers compiled using an old obstack.h can no @@ -45,82 +41,58 @@ files, it is simpler to just do this in the source for each such file. */ #include /* Random thing to get __GNU_LIBRARY__. */ -#if !defined _LIBC && defined __GNU_LIBRARY__ && __GNU_LIBRARY__ > 1 -# include -# if _GNU_OBSTACK_INTERFACE_VERSION == OBSTACK_INTERFACE_VERSION -# define ELIDE_CODE -# endif +#if !defined (_LIBC) && defined (__GNU_LIBRARY__) && __GNU_LIBRARY__ > 1 +#include +#if _GNU_OBSTACK_INTERFACE_VERSION == OBSTACK_INTERFACE_VERSION +#define ELIDE_CODE +#endif #endif -#include #ifndef ELIDE_CODE -# if HAVE_INTTYPES_H -# include -# endif -# if HAVE_STDINT_H || defined _LIBC -# include -# endif +#define POINTER void * /* Determine default alignment. */ -union fooround -{ - uintmax_t i; - long double d; - void *p; -}; -struct fooalign -{ - char c; - union fooround u; -}; +struct fooalign {char x; double d;}; +#define DEFAULT_ALIGNMENT \ + ((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. */ -enum - { - DEFAULT_ALIGNMENT = offsetof (struct fooalign, u), - DEFAULT_ROUNDING = sizeof (union fooround) - }; +union fooround {long x; double d;}; +#define DEFAULT_ROUNDING (sizeof (union fooround)) /* When we copy a long block of data, this is the unit to do it with. On some machines, copying successive ints does not work; in such a case, redefine COPYING_UNIT to `long' (if that works) or `char' as a last resort. */ -# ifndef COPYING_UNIT -# define COPYING_UNIT int -# endif +#ifndef COPYING_UNIT +#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 + 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. */ -# include -# ifdef _LIBC +#if defined __GNU_LIBRARY__ || defined HAVE_STDLIB_H +#include +#endif +#ifndef EXIT_FAILURE +#define EXIT_FAILURE 1 +#endif int obstack_exit_failure = EXIT_FAILURE; -# else -# include "exitfail.h" -# define obstack_exit_failure exit_failure -# endif -# ifdef _LIBC -# if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_3_4) -/* A looong time ago (before 1994, anyway; we're not sure) this global variable - was used by non-GNU-C macros to avoid multiple evaluation. The GNU C - library still exports it because somebody might use it. */ -struct obstack *_obstack_compat; -compat_symbol (libc, _obstack_compat, _obstack, GLIBC_2_0); -# endif -# endif +/* The non-GNU-C macros copy the obstack into this global variable + to avoid multiple evaluation. */ + +struct obstack *_obstack; /* Define a macro that either calls functions with the traditional malloc/free calling interface, or calls functions with the mmalloc/mfree interface @@ -128,18 +100,33 @@ compat_symbol (libc, _obstack_compat, _obstack, GLIBC_2_0); For free, do not use ?:, since some compilers, like the MIPS compilers, do not allow (expr) ? void : void. */ -# define CALL_CHUNKFUN(h, size) \ +#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) \ +#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)) \ + : (*(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). @@ -147,19 +134,18 @@ compat_symbol (libc, _obstack_compat, _obstack, GLIBC_2_0); CHUNKFUN is the function to use to allocate chunks, and FREEFUN the function to free them. - Return nonzero if successful, calls obstack_alloc_failed_handler if - allocation fails. */ + 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 (struct obstack *h, - int size, int alignment, - void *(*chunkfun) (long), - void (*freefun) (void *)) +_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. */ { @@ -186,8 +172,7 @@ _obstack_begin (struct obstack *h, chunk = h->chunk = CALL_CHUNKFUN (h, h -> chunk_size); if (!chunk) (*obstack_alloc_failed_handler) (); - h->next_free = h->object_base = __PTR_ALIGN ((char *) chunk, chunk->contents, - alignment - 1); + h->next_free = h->object_base = chunk->contents; h->chunk_limit = chunk->limit = (char *) chunk + h->chunk_size; chunk->prev = 0; @@ -199,14 +184,13 @@ _obstack_begin (struct obstack *h, int _obstack_begin_1 (struct obstack *h, int size, int alignment, - void *(*chunkfun) (void *, long), - void (*freefun) (void *, void *), - void *arg) + 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. */ { @@ -234,8 +218,7 @@ _obstack_begin_1 (struct obstack *h, int size, int alignment, chunk = h->chunk = CALL_CHUNKFUN (h, h -> chunk_size); if (!chunk) (*obstack_alloc_failed_handler) (); - h->next_free = h->object_base = __PTR_ALIGN ((char *) chunk, chunk->contents, - alignment - 1); + h->next_free = h->object_base = chunk->contents; h->chunk_limit = chunk->limit = (char *) chunk + h->chunk_size; chunk->prev = 0; @@ -260,10 +243,9 @@ _obstack_newchunk (struct obstack *h, int length) register long obj_size = h->next_free - h->object_base; register long i; long already; - char *object_base; /* Compute size for new chunk. */ - new_size = (obj_size + length) + (obj_size >> 3) + h->alignment_mask + 100; + new_size = (obj_size + length) + (obj_size >> 3) + 100; if (new_size < h->chunk_size) new_size = h->chunk_size; @@ -275,10 +257,6 @@ _obstack_newchunk (struct obstack *h, int length) new_chunk->prev = old_chunk; new_chunk->limit = h->chunk_limit = (char *) new_chunk + new_size; - /* Compute an aligned object_base in the new chunk */ - object_base = - __PTR_ALIGN ((char *) new_chunk, new_chunk->contents, h->alignment_mask); - /* Move the existing object to the new chunk. Word at a time is fast and is safe if the object is sufficiently aligned. */ @@ -286,7 +264,7 @@ _obstack_newchunk (struct obstack *h, int length) { for (i = obj_size / sizeof (COPYING_UNIT) - 1; i >= 0; i--) - ((COPYING_UNIT *)object_base)[i] + ((COPYING_UNIT *)new_chunk->contents)[i] = ((COPYING_UNIT *)h->object_base)[i]; /* We used to copy the odd few remaining bytes as one extra COPYING_UNIT, but that can cross a page boundary on a machine @@ -297,28 +275,22 @@ _obstack_newchunk (struct obstack *h, int length) already = 0; /* Copy remaining bytes one by one. */ for (i = already; i < obj_size; i++) - object_base[i] = h->object_base[i]; + new_chunk->contents[i] = h->object_base[i]; /* If the object just copied was the only data in OLD_CHUNK, free that chunk and remove it from the chain. But not if that chunk might contain an empty object. */ - if (! h->maybe_empty_object - && (h->object_base - == __PTR_ALIGN ((char *) old_chunk, old_chunk->contents, - h->alignment_mask))) + if (h->object_base == old_chunk->contents && ! h->maybe_empty_object) { new_chunk->prev = old_chunk->prev; CALL_FREEFUN (h, old_chunk); } - h->object_base = object_base; + h->object_base = new_chunk->contents; h->next_free = h->object_base + obj_size; /* The new chunk certainly contains no empty object yet. */ h->maybe_empty_object = 0; } -# ifdef _LIBC -libc_hidden_def (_obstack_newchunk) -# endif /* Return nonzero if object OBJ has been allocated from obstack H. This is here for debugging. @@ -326,10 +298,10 @@ libc_hidden_def (_obstack_newchunk) /* 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, void *obj); +int _obstack_allocated_p (struct obstack *h, POINTER obj); int -_obstack_allocated_p (struct obstack *h, void *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 */ @@ -338,7 +310,7 @@ _obstack_allocated_p (struct obstack *h, void *obj) /* 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 && ((void *) lp >= obj || (void *) (lp)->limit < obj)) + while (lp != 0 && ((POINTER) lp >= obj || (POINTER) (lp)->limit < obj)) { plp = lp->prev; lp = plp; @@ -349,10 +321,13 @@ _obstack_allocated_p (struct obstack *h, void *obj) /* Free objects in obstack H, including OBJ and everything allocate more recently than OBJ. If OBJ is zero, free everything in H. */ -# undef obstack_free +#undef obstack_free + +/* This function has two names with identical definitions. + This is the first one, called from non-ANSI code. */ void -obstack_free (struct obstack *h, void *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 */ @@ -361,7 +336,7 @@ obstack_free (struct obstack *h, void *obj) /* 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 && ((void *) lp >= obj || (void *) (lp)->limit < obj)) + while (lp != 0 && ((POINTER) lp >= obj || (POINTER) (lp)->limit < obj)) { plp = lp->prev; CALL_FREEFUN (h, lp); @@ -381,11 +356,37 @@ obstack_free (struct obstack *h, void *obj) abort (); } -# ifdef _LIBC -/* Older versions of libc used a function _obstack_free intended to be - called by non-GCC compilers. */ -strong_alias (obstack_free, _obstack_free) -# endif +/* This function is used from ANSI code. */ + +void +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 */ + + 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)) + { + plp = lp->prev; + CALL_FREEFUN (h, lp); + lp = plp; + /* If we switch chunks, we can't tell whether the new current + chunk contains an empty object, so assume that it may. */ + h->maybe_empty_object = 1; + } + if (lp) + { + h->object_base = h->next_free = (char *) (obj); + h->chunk_limit = lp->limit; + h->chunk = lp; + } + else if (obj != 0) + /* obj is not in any of the chunks! */ + abort (); +} int _obstack_memory_used (struct obstack *h) @@ -401,42 +402,109 @@ _obstack_memory_used (struct obstack *h) } /* Define the error handler. */ -# ifdef _LIBC +#ifndef _ +# if (HAVE_LIBINTL_H && ENABLE_NLS) || defined _LIBC # include -# else -# include "gettext.h" -# endif -# ifndef _ -# define _(msgid) gettext (msgid) -# endif - -# ifdef _LIBC -# include -# endif - -# ifndef __attribute__ -/* This feature is available in gcc versions 2.5 and later. */ -# if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 5) -# define __attribute__(Spec) /* empty */ +# ifndef _ +# define _(Str) gettext (Str) # endif +# else +# define _(Str) (Str) # endif +#endif static void -__attribute__ ((noreturn)) print_and_abort (void) { - /* Don't change any of these strings. Yes, it would be possible to add - the newline to the string and use fputs or so. But this must not - happen because the "memory exhausted" message appears in other places - like this and the translation should be reused instead of creating - a very similar string which requires a separate translation. */ -# ifdef _LIBC - (void) __fxprintf (NULL, "%s\n", _("memory exhausted")); -# else - fprintf (stderr, "%s\n", _("memory exhausted")); -# endif + 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. */ + +/* Now define the functional versions of the obstack macros. + Define them to simply use the corresponding macros to do the job. */ + +/* The function names appear in parentheses in order to prevent + the macro-definitions of the names from being expanded there. */ + +POINTER (obstack_base) (struct obstack *obstack) +{ + return obstack_base (obstack); +} + +POINTER (obstack_next_free) (struct obstack *obstack) +{ + return obstack_next_free (obstack); +} + +int (obstack_object_size) (struct obstack *obstack) +{ + return obstack_object_size (obstack); +} + +int (obstack_room) (struct obstack *obstack) +{ + return obstack_room (obstack); +} + +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) (struct obstack *obstack, POINTER pointer, int length) +{ + obstack_grow0 (obstack, pointer, length); +} + +void (obstack_1grow) (struct obstack *obstack, int character) +{ + obstack_1grow (obstack, character); +} + +void (obstack_blank) (struct obstack *obstack, int length) +{ + obstack_blank (obstack, length); +} + +void (obstack_1grow_fast) (struct obstack *obstack, int character) +{ + obstack_1grow_fast (obstack, character); +} + +void (obstack_blank_fast) (struct obstack *obstack, int length) +{ + obstack_blank_fast (obstack, length); +} + +POINTER (obstack_finish) (struct obstack *obstack) +{ + return obstack_finish (obstack); +} + +POINTER (obstack_alloc) (struct obstack *obstack, int length) +{ + return obstack_alloc (obstack, length); +} + +POINTER (obstack_copy) (struct obstack *obstack, POINTER pointer, int length) +{ + return obstack_copy (obstack, pointer, length); +} + +POINTER (obstack_copy0) (struct obstack *obstack, POINTER pointer, int length) +{ + return obstack_copy0 (obstack, pointer, length); +} + +#endif /* 0 */ #endif /* !ELIDE_CODE */ - diff --git a/obstack.h b/obstack.h index 1e062c5..23487ba 100644 --- a/obstack.h +++ b/obstack.h @@ -1,22 +1,26 @@ /* obstack.h - object stack macros - Copyright (C) 1988-1994,1996-1999,2003,2004,2005,2009,2011 - Free Software Foundation, Inc. - This file is part of the GNU C Library. + Copyright 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1996, 1997, 1998, + 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2008 + Free Software Foundation, Inc. - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - The GNU C Library is distributed in the hope that it will be useful, + NOTE: The canonical source of this file is maintained with the GNU C Library. + Bugs can be reported to bug-glibc@gnu.org. + + 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 - Lesser General Public License for more details. + 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 Lesser General Public - License along with the GNU C Library; if not, write to the Free - Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. */ + 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. */ /* Summary: @@ -110,36 +114,45 @@ Summary: extern "C" { #endif -/* We need the type of a pointer subtraction. If __PTRDIFF_TYPE__ is +/* We use subtraction of (char *) 0 instead of casting to int + because on word-addressable machines a simple cast to int + may ignore the byte-within-word field of the pointer. */ + +#ifndef __PTR_TO_INT +# define __PTR_TO_INT(P) ((P) - (char *) 0) +#endif + +#ifndef __INT_TO_PTR +# define __INT_TO_PTR(P) ((P) + (char *) 0) +#endif + +/* We need the type of the resulting object. If __PTRDIFF_TYPE__ is defined, as with GNU C, use that; that way we don't pollute the - namespace with 's symbols. Otherwise, include - and use ptrdiff_t. */ + namespace with 's symbols. Otherwise, if is + available, include it and use ptrdiff_t. In traditional C, long is + the best that we can do. */ #ifdef __PTRDIFF_TYPE__ # define PTR_INT_TYPE __PTRDIFF_TYPE__ #else -# include -# define PTR_INT_TYPE ptrdiff_t +# ifdef HAVE_STDDEF_H +# include +# define PTR_INT_TYPE ptrdiff_t +# else +# define PTR_INT_TYPE long +# endif #endif -/* If B is the base of an object addressed by P, return the result of - aligning P to the next multiple of A + 1. B and P must be of type - char *. A + 1 must be a power of 2. */ - -#define __BPTR_ALIGN(B, P, A) ((B) + (((P) - (B) + (A)) & ~(A))) - -/* Similiar to _BPTR_ALIGN (B, P, A), except optimize the common case - where pointers can be converted to integers, aligned as integers, - and converted back again. If PTR_INT_TYPE is narrower than a - pointer (e.g., the AS/400), play it safe and compute the alignment - relative to B. Otherwise, use the faster strategy of computing the - alignment relative to 0. */ - -#define __PTR_ALIGN(B, P, A) \ - __BPTR_ALIGN (sizeof (PTR_INT_TYPE) < sizeof (void *) ? (B) : (char *) 0, \ - P, A) - -#include +#if defined _LIBC || defined HAVE_STRING_H +# include +# define _obstack_memcpy(To, From, N) memcpy ((To), (From), (N)) +#else +# ifdef memcpy +# define _obstack_memcpy(To, From, N) memcpy ((To), (char *)(From), (N)) +# else +# define _obstack_memcpy(To, From, N) bcopy ((char *)(From), (To), (N)) +# endif +#endif struct _obstack_chunk /* Lives at front of each chunk. */ { @@ -155,11 +168,7 @@ struct obstack /* control current object in current chunk */ char *object_base; /* address of object we are building */ char *next_free; /* where to add next char to current object */ char *chunk_limit; /* address of char after current chunk */ - union - { - PTR_INT_TYPE tempint; - void *tempptr; - } temp; /* Temporary for some macros. */ + PTR_INT_TYPE temp; /* Temporary for some macros. */ int alignment_mask; /* Mask of alignment for each object. */ /* These prototypes vary based on `use_extra_arg', and we use casts to the prototypeless function type in all assignments, @@ -180,20 +189,55 @@ struct obstack /* control current object in current chunk */ /* Declare the external functions we use; they are in obstack.c. */ extern void _obstack_newchunk (struct obstack *, int); +extern void _obstack_free (struct obstack *, void *); extern int _obstack_begin (struct obstack *, int, int, void *(*) (long), void (*) (void *)); extern int _obstack_begin_1 (struct obstack *, int, int, void *(*) (void *, long), void (*) (void *, void *), void *); extern int _obstack_memory_used (struct obstack *); - -void obstack_free (struct obstack *__obstack, void *__block); - +/* Do the function-declarations after the structs + but before defining the macros. */ + +void obstack_init (struct obstack *obstack); + +void * obstack_alloc (struct obstack *obstack, int size); + +void * obstack_copy (struct obstack *obstack, void *address, int size); +void * obstack_copy0 (struct obstack *obstack, void *address, int size); + +void obstack_free (struct obstack *obstack, void *block); + +void obstack_blank (struct obstack *obstack, int size); + +void obstack_grow (struct obstack *obstack, void *data, int size); +void obstack_grow0 (struct obstack *obstack, void *data, int size); + +void obstack_1grow (struct obstack *obstack, int data_char); +void obstack_ptr_grow (struct obstack *obstack, void *data); +void obstack_int_grow (struct obstack *obstack, int data); + +void * obstack_finish (struct obstack *obstack); + +int obstack_object_size (struct obstack *obstack); + +int obstack_room (struct obstack *obstack); +void obstack_make_room (struct obstack *obstack, int size); +void obstack_1grow_fast (struct obstack *obstack, int data_char); +void obstack_ptr_grow_fast (struct obstack *obstack, void *data); +void obstack_int_grow_fast (struct obstack *obstack, int data); +void obstack_blank_fast (struct obstack *obstack, int size); + +void * obstack_base (struct obstack *obstack); +void * obstack_next_free (struct obstack *obstack); +int obstack_alignment_mask (struct obstack *obstack); +int obstack_chunk_size (struct obstack *obstack); +int obstack_memory_used (struct obstack *obstack); + /* Error handler called when `obstack_chunk_alloc' failed to allocate - more memory. This can be set to a user defined function which - should either abort gracefully or use longjump - but shouldn't - return. The default action is to print a message and abort. */ + more memory. This can be set to a user defined function. The + default action is to print a message and abort. */ extern void (*obstack_alloc_failed_handler) (void); /* Exit value used when `print_and_abort' is used. */ @@ -203,7 +247,7 @@ extern int obstack_exit_failure; Note that this might not be the final address of the object because a new chunk might be needed to hold the final size. */ -#define obstack_base(h) ((void *) (h)->object_base) +#define obstack_base(h) ((h)->object_base) /* Size for allocating ordinary chunks. */ @@ -217,31 +261,29 @@ extern int obstack_exit_failure; #define obstack_alignment_mask(h) ((h)->alignment_mask) -/* To prevent prototype warnings provide complete argument list. */ -#define obstack_init(h) \ - _obstack_begin ((h), 0, 0, \ - (void *(*) (long)) obstack_chunk_alloc, \ - (void (*) (void *)) obstack_chunk_free) +/* To prevent prototype warnings provide complete argument list in + standard C version. */ +# define obstack_init(h) \ + _obstack_begin ((h), 0, 0, \ + (void *(*) (long)) obstack_chunk_alloc, (void (*) (void *)) obstack_chunk_free) -#define obstack_begin(h, size) \ - _obstack_begin ((h), (size), 0, \ - (void *(*) (long)) obstack_chunk_alloc, \ - (void (*) (void *)) obstack_chunk_free) +# define obstack_begin(h, size) \ + _obstack_begin ((h), (size), 0, \ + (void *(*) (long)) obstack_chunk_alloc, (void (*) (void *)) obstack_chunk_free) -#define obstack_specify_allocation(h, size, alignment, chunkfun, freefun) \ - _obstack_begin ((h), (size), (alignment), \ - (void *(*) (long)) (chunkfun), \ - (void (*) (void *)) (freefun)) +# define obstack_specify_allocation(h, size, alignment, chunkfun, freefun) \ + _obstack_begin ((h), (size), (alignment), \ + (void *(*) (long)) (chunkfun), (void (*) (void *)) (freefun)) -#define obstack_specify_allocation_with_arg(h, size, alignment, chunkfun, freefun, arg) \ - _obstack_begin_1 ((h), (size), (alignment), \ - (void *(*) (void *, long)) (chunkfun), \ +# define obstack_specify_allocation_with_arg(h, size, alignment, chunkfun, freefun, arg) \ + _obstack_begin_1 ((h), (size), (alignment), \ + (void *(*) (void *, long)) (chunkfun), \ (void (*) (void *, void *)) (freefun), (arg)) -#define obstack_chunkfun(h, newchunkfun) \ +# define obstack_chunkfun(h, newchunkfun) \ ((h) -> chunkfun = (struct _obstack_chunk *(*)(void *, long)) (newchunkfun)) -#define obstack_freefun(h, newfreefun) \ +# define obstack_freefun(h, newfreefun) \ ((h) -> freefun = (void (*)(void *, struct _obstack_chunk *)) (newfreefun)) #define obstack_1grow_fast(h,achar) (*((h)->next_free)++ = (achar)) @@ -265,12 +307,12 @@ extern int obstack_exit_failure; # define obstack_object_size(OBSTACK) \ __extension__ \ - ({ struct obstack const *__o = (OBSTACK); \ + ({ struct obstack *__o = (OBSTACK); \ (unsigned) (__o->next_free - __o->object_base); }) # define obstack_room(OBSTACK) \ __extension__ \ - ({ struct obstack const *__o = (OBSTACK); \ + ({ struct obstack *__o = (OBSTACK); \ (unsigned) (__o->chunk_limit - __o->next_free); }) # define obstack_make_room(OBSTACK,length) \ @@ -283,11 +325,8 @@ __extension__ \ # define obstack_empty_p(OBSTACK) \ __extension__ \ - ({ struct obstack const *__o = (OBSTACK); \ - (__o->chunk->prev == 0 \ - && __o->next_free == __PTR_ALIGN ((char *) __o->chunk, \ - __o->chunk->contents, \ - __o->alignment_mask)); }) + ({ struct obstack *__o = (OBSTACK); \ + (__o->chunk->prev == 0 && __o->next_free - __o->chunk->contents == 0); }) # define obstack_grow(OBSTACK,where,length) \ __extension__ \ @@ -295,7 +334,7 @@ __extension__ \ int __len = (length); \ if (__o->next_free + __len > __o->chunk_limit) \ _obstack_newchunk (__o, __len); \ - memcpy (__o->next_free, where, __len); \ + _obstack_memcpy (__o->next_free, (where), __len); \ __o->next_free += __len; \ (void) 0; }) @@ -305,7 +344,7 @@ __extension__ \ int __len = (length); \ if (__o->next_free + __len + 1 > __o->chunk_limit) \ _obstack_newchunk (__o, __len + 1); \ - memcpy (__o->next_free, where, __len); \ + _obstack_memcpy (__o->next_free, (where), __len); \ __o->next_free += __len; \ *(__o->next_free)++ = 0; \ (void) 0; }) @@ -318,8 +357,8 @@ __extension__ \ obstack_1grow_fast (__o, datum); \ (void) 0; }) -/* These assume that the obstack alignment is good enough for pointers - or ints, and that the data added so far to the current object +/* These assume that the obstack alignment is good enough for pointers or ints, + and that the data added so far to the current object shares that much alignment. */ # define obstack_ptr_grow(OBSTACK,datum) \ @@ -327,7 +366,7 @@ __extension__ \ ({ struct obstack *__o = (OBSTACK); \ if (__o->next_free + sizeof (void *) > __o->chunk_limit) \ _obstack_newchunk (__o, sizeof (void *)); \ - obstack_ptr_grow_fast (__o, datum); }) \ + obstack_ptr_grow_fast (__o, datum); }) # define obstack_int_grow(OBSTACK,datum) \ __extension__ \ @@ -379,27 +418,28 @@ __extension__ \ /* The local variable is named __o1 to avoid a name conflict when obstack_blank is called. */ -# define obstack_finish(OBSTACK) \ +# define obstack_finish(OBSTACK) \ __extension__ \ ({ struct obstack *__o1 = (OBSTACK); \ - void *__value = (void *) __o1->object_base; \ - if (__o1->next_free == __value) \ + void *value; \ + value = (void *) __o1->object_base; \ + if (__o1->next_free == value) \ __o1->maybe_empty_object = 1; \ __o1->next_free \ - = __PTR_ALIGN (__o1->object_base, __o1->next_free, \ - __o1->alignment_mask); \ + = __INT_TO_PTR ((__PTR_TO_INT (__o1->next_free)+__o1->alignment_mask)\ + & ~ (__o1->alignment_mask)); \ if (__o1->next_free - (char *)__o1->chunk \ > __o1->chunk_limit - (char *)__o1->chunk) \ __o1->next_free = __o1->chunk_limit; \ __o1->object_base = __o1->next_free; \ - __value; }) + value; }) # define obstack_free(OBSTACK, OBJ) \ __extension__ \ ({ struct obstack *__o = (OBSTACK); \ - void *__obj = (OBJ); \ + void *__obj = (void *) (OBJ); \ if (__obj > (void *)__o->chunk && __obj < (void *)__o->chunk_limit) \ - __o->next_free = __o->object_base = (char *)__obj; \ + __o->next_free = __o->object_base = (char *) __obj; \ else (obstack_free) (__o, __obj); }) #else /* not __GNUC__ or not __STDC__ */ @@ -411,10 +451,7 @@ __extension__ \ (unsigned) ((h)->chunk_limit - (h)->next_free) # define obstack_empty_p(h) \ - ((h)->chunk->prev == 0 \ - && (h)->next_free == __PTR_ALIGN ((char *) (h)->chunk, \ - (h)->chunk->contents, \ - (h)->alignment_mask)) + ((h)->chunk->prev == 0 && (h)->next_free - (h)->chunk->contents == 0) /* Note that the call to _obstack_newchunk is enclosed in (..., 0) so that we can avoid having void expressions @@ -423,23 +460,23 @@ __extension__ \ but some compilers won't accept it. */ # define obstack_make_room(h,length) \ -( (h)->temp.tempint = (length), \ - (((h)->next_free + (h)->temp.tempint > (h)->chunk_limit) \ - ? (_obstack_newchunk ((h), (h)->temp.tempint), 0) : 0)) +( (h)->temp = (length), \ + (((h)->next_free + (h)->temp > (h)->chunk_limit) \ + ? (_obstack_newchunk ((h), (h)->temp), 0) : 0)) # define obstack_grow(h,where,length) \ -( (h)->temp.tempint = (length), \ - (((h)->next_free + (h)->temp.tempint > (h)->chunk_limit) \ - ? (_obstack_newchunk ((h), (h)->temp.tempint), 0) : 0), \ - memcpy ((h)->next_free, where, (h)->temp.tempint), \ - (h)->next_free += (h)->temp.tempint) +( (h)->temp = (length), \ + (((h)->next_free + (h)->temp > (h)->chunk_limit) \ + ? (_obstack_newchunk ((h), (h)->temp), 0) : 0), \ + _obstack_memcpy ((h)->next_free, (where), (h)->temp), \ + (h)->next_free += (h)->temp) # define obstack_grow0(h,where,length) \ -( (h)->temp.tempint = (length), \ - (((h)->next_free + (h)->temp.tempint + 1 > (h)->chunk_limit) \ - ? (_obstack_newchunk ((h), (h)->temp.tempint + 1), 0) : 0), \ - memcpy ((h)->next_free, where, (h)->temp.tempint), \ - (h)->next_free += (h)->temp.tempint, \ +( (h)->temp = (length), \ + (((h)->next_free + (h)->temp + 1 > (h)->chunk_limit) \ + ? (_obstack_newchunk ((h), (h)->temp + 1), 0) : 0), \ + _obstack_memcpy ((h)->next_free, (where), (h)->temp), \ + (h)->next_free += (h)->temp, \ *((h)->next_free)++ = 0) # define obstack_1grow(h,datum) \ @@ -461,13 +498,13 @@ __extension__ \ (((const void **) ((h)->next_free += sizeof (void *)))[-1] = (aptr)) # define obstack_int_grow_fast(h,aint) \ - (((int *) ((h)->next_free += sizeof (int)))[-1] = (aint)) + (((int *) ((h)->next_free += sizeof (int)))[-1] = (aptr)) # define obstack_blank(h,length) \ -( (h)->temp.tempint = (length), \ - (((h)->chunk_limit - (h)->next_free < (h)->temp.tempint) \ - ? (_obstack_newchunk ((h), (h)->temp.tempint), 0) : 0), \ - obstack_blank_fast (h, (h)->temp.tempint)) +( (h)->temp = (length), \ + (((h)->chunk_limit - (h)->next_free < (h)->temp) \ + ? (_obstack_newchunk ((h), (h)->temp), 0) : 0), \ + obstack_blank_fast (h, (h)->temp)) # define obstack_alloc(h,length) \ (obstack_blank ((h), (length)), obstack_finish ((h))) @@ -478,27 +515,26 @@ __extension__ \ # define obstack_copy0(h,where,length) \ (obstack_grow0 ((h), (where), (length)), obstack_finish ((h))) -# define obstack_finish(h) \ +# define obstack_finish(h) \ ( ((h)->next_free == (h)->object_base \ ? (((h)->maybe_empty_object = 1), 0) \ : 0), \ - (h)->temp.tempptr = (h)->object_base, \ + (h)->temp = __PTR_TO_INT ((h)->object_base), \ (h)->next_free \ - = __PTR_ALIGN ((h)->object_base, (h)->next_free, \ - (h)->alignment_mask), \ + = __INT_TO_PTR ((__PTR_TO_INT ((h)->next_free)+(h)->alignment_mask) \ + & ~ ((h)->alignment_mask)), \ (((h)->next_free - (char *) (h)->chunk \ > (h)->chunk_limit - (char *) (h)->chunk) \ ? ((h)->next_free = (h)->chunk_limit) : 0), \ (h)->object_base = (h)->next_free, \ - (h)->temp.tempptr) + (void *) __INT_TO_PTR ((h)->temp)) # define obstack_free(h,obj) \ -( (h)->temp.tempint = (char *) (obj) - (char *) (h)->chunk, \ - ((((h)->temp.tempint > 0 \ - && (h)->temp.tempint < (h)->chunk_limit - (char *) (h)->chunk)) \ +( (h)->temp = (char *) (obj) - (char *) (h)->chunk, \ + (((h)->temp > 0 && (h)->temp < (h)->chunk_limit - (char *) (h)->chunk)\ ? (((h)->next_free = (h)->object_base \ - = (h)->temp.tempint + (char *) (h)->chunk), 0) \ - : ((obstack_free) ((h), (h)->temp.tempint + (char *) (h)->chunk), 0))) + = (h)->temp + (char *) (h)->chunk), 0) \ + : ((obstack_free) ((h), (h)->temp + (char *) (h)->chunk), 0))) #endif /* not __GNUC__ or not __STDC__ */ @@ -507,4 +543,3 @@ __extension__ \ #endif #endif /* obstack.h */ -