From e9f48dc1f8fd7ab78f5b25ef0513e2635d37b707 Mon Sep 17 00:00:00 2001 From: Wojciech Polak Date: Fri, 17 Dec 2004 22:46:57 +0000 Subject: Provide newer version. --- lib/obstack.c | 84 +++++++++++++++++++++----------- lib/obstack.h | 151 +++++++++++++++++++++++++--------------------------------- 2 files changed, 122 insertions(+), 113 deletions(-) (limited to 'lib') diff --git a/lib/obstack.c b/lib/obstack.c index d8bea0a..25cb9ab 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 @@ -22,9 +23,10 @@ #endif #ifdef _LIBC -#include +# include +# include #else -#include "obstack.h" +# include "obstack.h" #endif /* NOTE BEFORE MODIFYING THIS FILE: This version number must be @@ -53,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; @@ -86,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 @@ -133,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. */ { @@ -160,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; @@ -179,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. */ { @@ -207,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; @@ -249,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 @@ -275,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); @@ -286,9 +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 +# ifdef _LIBC libc_hidden_def (_obstack_newchunk) -#endif +# endif /* Return nonzero if object OBJ has been allocated from obstack H. This is here for debugging. @@ -351,11 +379,11 @@ obstack_free (struct obstack *h, void *obj) abort (); } -#ifdef _LIBC +# 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 +# endif int _obstack_memory_used (struct obstack *h) @@ -376,7 +404,9 @@ _obstack_memory_used (struct obstack *h) # else # include "gettext.h" # endif -# define _(msgid) gettext (msgid) +# ifndef _ +# define _(msgid) gettext (msgid) +# endif # ifdef _LIBC # include diff --git a/lib/obstack.h b/lib/obstack.h index 1460f5d..46a1cb7 100644 --- a/lib/obstack.h +++ b/lib/obstack.h @@ -1,5 +1,5 @@ /* obstack.h - object stack macros - Copyright (C) 1988,89,90,91,92,93,94,96,97,98,99,2003 Free Software Foundation, Inc. + Copyright (C) 1988-1994,1996-1999,2003,2004 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. @@ -113,19 +113,7 @@ Summary: extern "C" { #endif -/* 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 +/* We need the type of a pointer subtraction. 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. */ @@ -137,6 +125,23 @@ extern "C" { # define PTR_INT_TYPE ptrdiff_t #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 struct _obstack_chunk /* Lives at front of each chunk. */ @@ -153,7 +158,11 @@ 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 */ - PTR_INT_TYPE temp; /* Temporary for some macros. */ + union + { + PTR_INT_TYPE tempint; + void *tempptr; + } 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, @@ -174,52 +183,16 @@ 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 *); - -/* 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, const void *address, int size); -void * obstack_copy0 (struct obstack *obstack, const 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, const void *data, int size); -void obstack_grow0 (struct obstack *obstack, const void *data, int size); - -void obstack_1grow (struct obstack *obstack, int data_char); -void obstack_ptr_grow (struct obstack *obstack, const 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, const 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 @@ -233,7 +206,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) ((h)->object_base) +#define obstack_base(h) ((void *) (h)->object_base) /* Size for allocating ordinary chunks. */ @@ -314,7 +287,10 @@ __extension__ \ # define obstack_empty_p(OBSTACK) \ __extension__ \ ({ struct obstack const *__o = (OBSTACK); \ - (__o->chunk->prev == 0 && __o->next_free - __o->chunk->contents == 0); }) + (__o->chunk->prev == 0 \ + && __o->next_free == __PTR_ALIGN ((char *) __o->chunk, \ + __o->chunk->contents, \ + __o->alignment_mask)); }) # define obstack_grow(OBSTACK,where,length) \ __extension__ \ @@ -409,18 +385,17 @@ __extension__ \ # define obstack_finish(OBSTACK) \ __extension__ \ ({ struct obstack *__o1 = (OBSTACK); \ - void *value; \ - value = (void *) __o1->object_base; \ - if (__o1->next_free == value) \ + void *__value = (void *) __o1->object_base; \ + if (__o1->next_free == __value) \ __o1->maybe_empty_object = 1; \ __o1->next_free \ - = __INT_TO_PTR ((__PTR_TO_INT (__o1->next_free)+__o1->alignment_mask)\ - & ~ (__o1->alignment_mask)); \ + = __PTR_ALIGN (__o1->object_base, __o1->next_free, \ + __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__ \ @@ -439,7 +414,10 @@ __extension__ \ (unsigned) ((h)->chunk_limit - (h)->next_free) # define obstack_empty_p(h) \ - ((h)->chunk->prev == 0 && (h)->next_free - (h)->chunk->contents == 0) + ((h)->chunk->prev == 0 \ + && (h)->next_free == __PTR_ALIGN ((char *) (h)->chunk, \ + (h)->chunk->contents, \ + (h)->alignment_mask)) /* Note that the call to _obstack_newchunk is enclosed in (..., 0) so that we can avoid having void expressions @@ -448,23 +426,23 @@ __extension__ \ but some compilers won't accept it. */ # define obstack_make_room(h,length) \ -( (h)->temp = (length), \ - (((h)->next_free + (h)->temp > (h)->chunk_limit) \ - ? (_obstack_newchunk ((h), (h)->temp), 0) : 0)) +( (h)->temp.tempint = (length), \ + (((h)->next_free + (h)->temp.tempint > (h)->chunk_limit) \ + ? (_obstack_newchunk ((h), (h)->temp.tempint), 0) : 0)) # define obstack_grow(h,where,length) \ -( (h)->temp = (length), \ - (((h)->next_free + (h)->temp > (h)->chunk_limit) \ - ? (_obstack_newchunk ((h), (h)->temp), 0) : 0), \ - memcpy ((h)->next_free, where, (h)->temp), \ - (h)->next_free += (h)->temp) +( (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) # define obstack_grow0(h,where,length) \ -( (h)->temp = (length), \ - (((h)->next_free + (h)->temp + 1 > (h)->chunk_limit) \ - ? (_obstack_newchunk ((h), (h)->temp + 1), 0) : 0), \ - memcpy ((h)->next_free, where, (h)->temp), \ - (h)->next_free += (h)->temp, \ +( (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)->next_free)++ = 0) # define obstack_1grow(h,datum) \ @@ -489,10 +467,10 @@ __extension__ \ (((int *) ((h)->next_free += sizeof (int)))[-1] = (aptr)) # define obstack_blank(h,length) \ -( (h)->temp = (length), \ - (((h)->chunk_limit - (h)->next_free < (h)->temp) \ - ? (_obstack_newchunk ((h), (h)->temp), 0) : 0), \ - obstack_blank_fast (h, (h)->temp)) +( (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)) # define obstack_alloc(h,length) \ (obstack_blank ((h), (length)), obstack_finish ((h))) @@ -507,22 +485,23 @@ __extension__ \ ( ((h)->next_free == (h)->object_base \ ? (((h)->maybe_empty_object = 1), 0) \ : 0), \ - (h)->temp = __PTR_TO_INT ((h)->object_base), \ + (h)->temp.tempptr = (h)->object_base, \ (h)->next_free \ - = __INT_TO_PTR ((__PTR_TO_INT ((h)->next_free)+(h)->alignment_mask) \ - & ~ ((h)->alignment_mask)), \ + = __PTR_ALIGN ((h)->object_base, (h)->next_free, \ + (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, \ - (void *) __INT_TO_PTR ((h)->temp)) + (h)->temp.tempptr) # define obstack_free(h,obj) \ -( (h)->temp = (char *) (obj) - (char *) (h)->chunk, \ - (((h)->temp > 0 && (h)->temp < (h)->chunk_limit - (char *) (h)->chunk)\ +( (h)->temp.tempint = (char *) (obj) - (char *) (h)->chunk, \ + ((((h)->temp.tempint > 0 \ + && (h)->temp.tempint < (h)->chunk_limit - (char *) (h)->chunk)) \ ? (int) ((h)->next_free = (h)->object_base \ - = (h)->temp + (char *) (h)->chunk) \ - : (((obstack_free) ((h), (h)->temp + (char *) (h)->chunk), 0), 0))) + = (h)->temp.tempint + (char *) (h)->chunk) \ + : (((obstack_free) ((h), (h)->temp.tempint + (char *) (h)->chunk), 0), 0))) #endif /* not __GNUC__ or not __STDC__ */ -- cgit v1.2.1