X-Git-Url: http://erislabs.net/gitweb/?a=blobdiff_plain;f=lib%2Fobstack.c;h=25cb9abba31c3845c44682ef176c1678dce32462;hb=e1bb3dab9a2dca414eab231c33afd3fad19e7924;hp=bf6bba86c1d2fd6b18f7755fb09a3ba1d134e1cb;hpb=1d31a1e7121fda63c28ca105309237f6fa98ab80;p=gnulib.git diff --git a/lib/obstack.c b/lib/obstack.c index bf6bba86c..25cb9abba 100644 --- a/lib/obstack.c +++ b/lib/obstack.c @@ -1,7 +1,8 @@ /* 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 Free Software Foundation, Inc. + 1998, 1999, 2000, 2001, 2002, 2003, 2004 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 @@ -21,7 +22,12 @@ # include #endif -#include "obstack.h" +#ifdef _LIBC +# include +# include +#else +# include "obstack.h" +#endif /* NOTE BEFORE MODIFYING THIS FILE: This version number must be incremented whenever callers compiled using an old obstack.h can no @@ -49,18 +55,33 @@ # include #endif +#include + #ifndef ELIDE_CODE +# if HAVE_INTTYPES_H +# include +# endif +# if HAVE_STDINT_H || defined _LIBC +# include +# endif + /* 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; +}; /* 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 { char c; union fooround u; }, 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; @@ -82,15 +103,22 @@ void (*obstack_alloc_failed_handler) (void) = print_and_abort; /* Exit value used when `print_and_abort' is used. */ # include -# ifndef _LIBC -# include "exit.h" -# endif +# ifdef _LIBC int obstack_exit_failure = EXIT_FAILURE; +# else +# include "exitfail.h" +# 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 @@ -129,7 +157,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. */ { @@ -156,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; @@ -175,7 +204,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. */ { @@ -203,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; @@ -245,8 +275,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 @@ -271,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); @@ -282,6 +314,9 @@ _obstack_newchunk (struct obstack *h, int length) /* 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. @@ -314,41 +349,6 @@ _obstack_allocated_p (struct obstack *h, void *obj) # 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) -{ - 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 && ((void *) lp >= obj || (void *) (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 (); -} - -/* This function is used from ANSI code. */ - void obstack_free (struct obstack *h, void *obj) { @@ -378,6 +378,12 @@ obstack_free (struct obstack *h, void *obj) /* obj is not in any of the chunks! */ 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 int _obstack_memory_used (struct obstack *h) @@ -398,11 +404,12 @@ _obstack_memory_used (struct obstack *h) # else # include "gettext.h" # endif -# define _(msgid) gettext (msgid) +# ifndef _ +# define _(msgid) gettext (msgid) +# endif -# if defined _LIBC && defined USE_IN_LIBIO +# ifdef _LIBC # include -# define fputs(s, f) _IO_fputs (s, f) # endif # ifndef __attribute__