X-Git-Url: http://erislabs.net/gitweb/?a=blobdiff_plain;f=lib%2Fobstack.c;h=25cb9abba31c3845c44682ef176c1678dce32462;hb=e1bb3dab9a2dca414eab231c33afd3fad19e7924;hp=9bbc3d4ca16eff768c9d4046917b9ab4b59fe6d4;hpb=e868156834d09d1a0b2046c3defac1691fcfd953;p=gnulib.git diff --git a/lib/obstack.c b/lib/obstack.c index 9bbc3d4ca..25cb9abba 100644 --- a/lib/obstack.c +++ b/lib/obstack.c @@ -24,6 +24,7 @@ #ifdef _LIBC # include +# include #else # include "obstack.h" #endif @@ -59,10 +60,17 @@ #ifndef ELIDE_CODE +# if HAVE_INTTYPES_H +# include +# endif +# if HAVE_STDINT_H || defined _LIBC +# include +# endif + /* Determine default alignment. */ union fooround { - long int i; + uintmax_t i; long double d; void *p; }; @@ -102,10 +110,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 @@ -171,7 +184,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; @@ -218,7 +232,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; @@ -285,7 +300,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);