diff options
Diffstat (limited to 'libc/misc/gnu')
| -rw-r--r-- | libc/misc/gnu/obstack.c | 422 | 
1 files changed, 123 insertions, 299 deletions
| diff --git a/libc/misc/gnu/obstack.c b/libc/misc/gnu/obstack.c index 8ed3e8ac0..239146383 100644 --- a/libc/misc/gnu/obstack.c +++ b/libc/misc/gnu/obstack.c @@ -1,7 +1,7 @@  /* obstack.c - subroutines used implicitly by object stack macros -   Copyright (C) 1988-1994,96,97,98,99,2000,2001 Free Software Foundation, Inc. -   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. +   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.     The GNU C Library is free software; you can redistribute it and/or     modify it under the terms of the GNU Lesser General Public @@ -15,19 +15,30 @@     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., 59 Temple Place, Suite 330, Boston, MA -   02111-1307 USA.  */ +   Software Foundation, Inc., 51 Franklin Street, Fifth Floor, +   Boston, MA 02110-1301, USA.  */ -/* Make uClibc lie about being glibc. */ -#define __FORCE_GLIBC 1 - -#include <locale.h>  #ifdef HAVE_CONFIG_H  # include <config.h>  #endif -#include <obstack.h> +#ifdef _LIBC +# include <obstack.h> +#ifndef __UCLIBC__ +# include <shlib-compat.h> +#else +# define HAVE_INTTYPES_H 1 +# define HAVE_STDINT_H 1 +# define SHLIB_COMPAT(x,y,z) 0 +# undef libc_hidden_def +# define libc_hidden_def(x) +# undef strong_alias +# define strong_alias(x,y) +#endif +#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 @@ -51,28 +62,38 @@  # endif  #endif -#if (defined _LIBC && defined USE_IN_LIBIO) || defined __UCLIBC_HAS_WCHAR__ -# include <wchar.h> -#endif +#include <stddef.h>  #ifndef ELIDE_CODE -# if defined __STDC__ && __STDC__ -#  define POINTER void * -# else -#  define POINTER char * +# if HAVE_INTTYPES_H +#  include <inttypes.h> +# endif +# if HAVE_STDINT_H || defined _LIBC +#  include <stdint.h>  # 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; +}; +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; @@ -89,36 +110,29 @@ union fooround {long x; double d;};     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 - +static void (*__obstack_alloc_failed_handler) (void) = print_and_abort; +weak_alias(__obstack_alloc_failed_handler,obstack_alloc_failed_handler)  /* 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 +# include <stdlib.h> +# ifdef _LIBC +static int __obstack_exit_failure = EXIT_FAILURE; +weak_alias(__obstack_exit_failure,obstack_exit_failure) +# else +#  include "exitfail.h" +#  define __obstack_exit_failure exit_failure  # endif -libc_hidden_proto(fprintf) -libc_hidden_proto(abort) -libc_hidden_proto(exit) -#ifdef __UCLIBC_HAS_WCHAR__ -libc_hidden_proto(fwprintf) -#endif - -int obstack_exit_failure = EXIT_FAILURE; - -/* 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 @@ -126,33 +140,18 @@ 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) \ +# 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). @@ -164,23 +163,15 @@ struct obstack *_obstack;     allocation fails.  */  int -_obstack_begin ( -     struct obstack *h, -     int size, -     int alignment, -# if defined __STDC__ && __STDC__ -     POINTER (*chunkfun) (long), -     void (*freefun) (void *) -# else -     POINTER (*chunkfun) (), -     void (*freefun) () -# endif -     ) +_obstack_begin (struct obstack *h, +		int size, int alignment, +		void *(*chunkfun) (long), +		void (*freefun) (void *))  {    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.  */      { @@ -198,21 +189,17 @@ _obstack_begin (        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; +    (*__obstack_alloc_failed_handler) (); +  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; @@ -223,23 +210,15 @@ _obstack_begin (  }  int -_obstack_begin_1 ( -     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) +_obstack_begin_1 (struct obstack *h, int size, int alignment, +		  void *(*chunkfun) (void *, long), +		  void (*freefun) (void *, void *), +		  void *arg)  {    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.  */      { @@ -257,13 +236,8 @@ _obstack_begin_1 (        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; @@ -271,8 +245,9 @@ _obstack_begin_1 (    chunk = h->chunk = CALL_CHUNKFUN (h, h -> chunk_size);    if (!chunk) -    (*obstack_alloc_failed_handler) (); -  h->next_free = h->object_base = chunk->contents; +    (*__obstack_alloc_failed_handler) (); +  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; @@ -289,9 +264,7 @@ _obstack_begin_1 (     to the beginning of the new one.  */  void -_obstack_newchunk ( -     struct obstack *h, -     int length) +_obstack_newchunk (struct obstack *h, int length)  {    register struct _obstack_chunk *old_chunk = h->chunk;    register struct _obstack_chunk *new_chunk; @@ -309,15 +282,14 @@ _obstack_newchunk (    /* Allocate and initialize the new chunk.  */    new_chunk = CALL_CHUNKFUN (h, new_size);    if (!new_chunk) -    (*obstack_alloc_failed_handler) (); +    (*__obstack_alloc_failed_handler) ();    h->chunk = new_chunk;    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 = -    __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 @@ -342,7 +314,10 @@ _obstack_newchunk (    /* 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); @@ -353,21 +328,20 @@ _obstack_newchunk (    /* 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.     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 (struct obstack *h, void *obj);  int -_obstack_allocated_p ( -     struct obstack *h, -     POINTER obj) +_obstack_allocated_p (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 */ @@ -376,7 +350,7 @@ _obstack_allocated_p (    /* 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)) +  while (lp != 0 && ((void *) lp >= obj || (void *) (lp)->limit < obj))      {        plp = lp->prev;        lp = plp; @@ -389,13 +363,8 @@ _obstack_allocated_p (  # 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, -     POINTER 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 */ @@ -404,7 +373,7 @@ _obstack_free (    /* 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 && ((void *) lp >= obj || (void *) (lp)->limit < obj))      {        plp = lp->prev;        CALL_FREEFUN (h, lp); @@ -424,43 +393,14 @@ _obstack_free (      abort ();  } -/* 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 (); -} +# 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) +_obstack_memory_used (struct obstack *h)  {    register struct _obstack_chunk* lp;    register int nbytes = 0; @@ -473,20 +413,27 @@ _obstack_memory_used (  }  /* Define the error handler.  */ +# ifdef _LIBC +#  include <libintl.h> +# else +#  include "gettext.h" +# endif +/* NLS: Disable gettext in obstack for now: */ +# undef _ +# define _(Str) (Str)  # ifndef _ -#  if ((HAVE_LIBINTL_H && ENABLE_NLS) || defined _LIBC) && \ -      defined __UCLIBC_HAS_GETTEXT_AWARENESS__ && 00 -#   include <libintl.h> -#   ifndef _ -#    define _(Str) INTUSE(__dcgettext) (NULL, Str, LC_MESSAGES) -#   endif -#  else -#   define _(Str) (Str) -#  endif +#  define _(msgid) gettext (msgid)  # endif -# if defined _LIBC && defined USE_IN_LIBIO + +# if defined _LIBC && !defined __UCLIBC__  #  include <libio/iolibio.h> -#  define fputs(s, f) _IO_fputs (s, f) +# 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 */ +#  endif  # endif  static void @@ -498,135 +445,12 @@ 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 +# if defined _LIBC && !defined __UCLIBC__ +  (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); -} - -# 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.  */ - -#  if defined __STDC__ && __STDC__ -/* These function definitions do not work with non-ANSI preprocessors; -   they won't pass through the macro names in parentheses.  */ - -/* The function names appear in parentheses in order to prevent -   the macro-definitions of the names from being expanded there.  */ - -POINTER (obstack_base) (obstack) -     struct obstack *obstack; -{ -  return obstack_base (obstack); -} - -POINTER (obstack_next_free) (obstack) -     struct obstack *obstack; -{ -  return obstack_next_free (obstack); -} - -int (obstack_object_size) (obstack) -     struct obstack *obstack; -{ -  return obstack_object_size (obstack); -} - -int (obstack_room) (obstack) -     struct obstack *obstack; -{ -  return obstack_room (obstack); -} - -int (obstack_make_room) (obstack, length) -     struct obstack *obstack; -     int length; -{ -  return obstack_make_room (obstack, length); +  exit (__obstack_exit_failure);  } -void (obstack_grow) (obstack, data, length) -     struct obstack *obstack; -     const POINTER data; -     int length; -{ -  obstack_grow (obstack, data, length); -} - -void (obstack_grow0) (obstack, data, length) -     struct obstack *obstack; -     const POINTER data; -     int length; -{ -  obstack_grow0 (obstack, data, length); -} - -void (obstack_1grow) (obstack, character) -     struct obstack *obstack; -     int character; -{ -  obstack_1grow (obstack, character); -} - -void (obstack_blank) (obstack, length) -     struct obstack *obstack; -     int length; -{ -  obstack_blank (obstack, length); -} - -void (obstack_1grow_fast) (obstack, character) -     struct obstack *obstack; -     int character; -{ -  obstack_1grow_fast (obstack, character); -} - -void (obstack_blank_fast) (obstack, length) -     struct obstack *obstack; -     int length; -{ -  obstack_blank_fast (obstack, length); -} - -POINTER (obstack_finish) (obstack) -     struct obstack *obstack; -{ -  return obstack_finish (obstack); -} - -POINTER (obstack_alloc) (obstack, length) -     struct obstack *obstack; -     int length; -{ -  return obstack_alloc (obstack, length); -} - -POINTER (obstack_copy) (obstack, address, length) -     struct obstack *obstack; -     const POINTER address; -     int length; -{ -  return obstack_copy (obstack, address, length); -} - -POINTER (obstack_copy0) (obstack, address, length) -     struct obstack *obstack; -     const POINTER address; -     int length; -{ -  return obstack_copy0 (obstack, address, length); -} - -#  endif /* __STDC__ */ - -# endif /* 0 */ -  #endif	/* !ELIDE_CODE */ | 
