X-Git-Url: http://erislabs.net/gitweb/?a=blobdiff_plain;f=lib%2Fobstack.c;h=5b87466d881f1df66874890eff3212a444f8700f;hb=1bf5f51e739b66371e96b8da60002fc23603d3f5;hp=6a1ca0086cc724d8261504f86cc0e9bbacf5d4d0;hpb=62506e7817689dd70311d3a6ad3fd8e4fbc4308c;p=gnulib.git diff --git a/lib/obstack.c b/lib/obstack.c index 6a1ca0086..5b87466d8 100644 --- a/lib/obstack.c +++ b/lib/obstack.c @@ -1,30 +1,27 @@ /* 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 Free Software Foundation, - Inc. + 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software + Foundation, Inc. - This program is free software; you can redistribute it and/or modify + 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. + the Free Software Foundation; either version 3 of the License, 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 -#endif + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ #ifdef _LIBC # include +# include #else +# include # include "obstack.h" #endif @@ -50,22 +47,32 @@ # endif #endif -#if defined _LIBC && defined USE_IN_LIBIO -# include -#endif +#include #ifndef ELIDE_CODE +# include /* Determine default alignment. */ -struct fooalign {char x; double d;}; -# define DEFAULT_ALIGNMENT \ - ((PTR_INT_TYPE) ((char *) &((struct fooalign *) 0)->d - (char *) 0)) +union fooround +{ + uintmax_t i; + long double d; + void *p; +}; +struct fooalign +{ + char c; + union fooround u; +}; /* 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. */ -union fooround {long x; double d;}; -# define DEFAULT_ROUNDING (sizeof (union fooround)) +enum + { + DEFAULT_ALIGNMENT = offsetof (struct fooalign, u), + 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; @@ -94,10 +101,15 @@ int obstack_exit_failure = EXIT_FAILURE; # define obstack_exit_failure exit_failure # endif -/* The non-GNU-C macros copy the obstack into this global variable - to avoid multiple evaluation. */ - -struct obstack *_obstack; +# 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 /* Define a macro that either calls functions with the traditional malloc/free calling interface, or calls functions with the mmalloc/mfree interface @@ -136,7 +148,7 @@ _obstack_begin (struct obstack *h, register struct _obstack_chunk *chunk; /* points to new chunk */ if (alignment == 0) - alignment = (int) DEFAULT_ALIGNMENT; + alignment = DEFAULT_ALIGNMENT; if (size == 0) /* Default size is what GNU malloc can fit in a 4096-byte block. */ { @@ -163,7 +175,8 @@ _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 = chunk->contents; + h->next_free = h->object_base = __PTR_ALIGN ((char *) chunk, chunk->contents, + alignment - 1); h->chunk_limit = chunk->limit = (char *) chunk + h->chunk_size; chunk->prev = 0; @@ -182,7 +195,7 @@ _obstack_begin_1 (struct obstack *h, int size, int alignment, register struct _obstack_chunk *chunk; /* points to new chunk */ if (alignment == 0) - alignment = (int) DEFAULT_ALIGNMENT; + alignment = DEFAULT_ALIGNMENT; if (size == 0) /* Default size is what GNU malloc can fit in a 4096-byte block. */ { @@ -210,7 +223,8 @@ _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 = chunk->contents; + h->next_free = h->object_base = __PTR_ALIGN ((char *) chunk, chunk->contents, + alignment - 1); h->chunk_limit = chunk->limit = (char *) chunk + h->chunk_size; chunk->prev = 0; @@ -252,8 +266,7 @@ _obstack_newchunk (struct obstack *h, int length) /* Compute an aligned object_base in the new chunk */ object_base = - __INT_TO_PTR ((__PTR_TO_INT (new_chunk->contents) + h->alignment_mask) - & ~ (h->alignment_mask)); + __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 @@ -278,7 +291,10 @@ _obstack_newchunk (struct obstack *h, int length) /* 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->object_base == old_chunk->contents && ! h->maybe_empty_object) + if (! h->maybe_empty_object + && (h->object_base + == __PTR_ALIGN ((char *) old_chunk, old_chunk->contents, + h->alignment_mask))) { new_chunk->prev = old_chunk->prev; CALL_FREEFUN (h, old_chunk); @@ -325,7 +341,7 @@ _obstack_allocated_p (struct obstack *h, void *obj) # undef obstack_free void -obstack_free (struct obstack *h, void *obj) +__obstack_free (struct obstack *h, void *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 */ @@ -403,12 +419,11 @@ print_and_abort (void) 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. */ -# if defined _LIBC && defined USE_IN_LIBIO - if (_IO_fwide (stderr, 0) > 0) - __fwprintf (stderr, L"%s\n", _("memory exhausted")); - else +# ifdef _LIBC + (void) __fxprintf (NULL, "%s\n", _("memory exhausted")); +# else + fprintf (stderr, "%s\n", _("memory exhausted")); # endif - fprintf (stderr, "%s\n", _("memory exhausted")); exit (obstack_exit_failure); }