Update to glibc 2.38

This commit is contained in:
Daryl Ronningen 2023-12-08 01:20:08 -08:00
parent 362629706c
commit 8d47da6c5c
Signed by: Daryl Ronningen
GPG key ID: FD23F0C934A5EC6B
3 changed files with 351 additions and 329 deletions

View file

@ -1,8 +1,8 @@
dnl Process this file with autoconf to produce a configure script
AC_PREREQ(2.69)
AC_PREREQ([2.71])
AC_INIT([obstack], [1.2], [pullmoll@t-online.de])
AC_INIT([obstack],[1.3],[pullmoll@t-online.de])
AM_INIT_AUTOMAKE([1.16])
AC_CONFIG_MACRO_DIR([m4])

353
obstack.c
View file

@ -1,5 +1,5 @@
/* obstack.c - subroutines used implicitly by object stack macros
Copyright (C) 1988-2020 Free Software Foundation, Inc.
Copyright (C) 1988-2023 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
@ -14,19 +14,21 @@
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
<https://www.gnu.org/licenses/>. */
#ifdef _LIBC
# include <obstack.h>
# include <shlib-compat.h>
#else
# include <config.h>
# include "obstack.h"
#endif
/* NOTE BEFORE MODIFYING THIS FILE: _OBSTACK_INTERFACE_VERSION in
obstack.h must be incremented whenever callers compiled using an old
obstack.h can no longer properly call the functions in this file. */
/* NOTE BEFORE MODIFYING THIS FILE: This version number must be
incremented whenever callers compiled using an old obstack.h can no
longer properly call the functions in this obstack.c. */
#define OBSTACK_INTERFACE_VERSION 1
/* Comment out all this code if we are using the GNU C Library, and are not
actually compiling the library itself, and the installed library
@ -36,83 +38,108 @@
(especially if it is a shared library). Rather than having every GNU
program understand 'configure --with-gnu-libc' and omit the object
files, it is simpler to just do this in the source for each such file. */
#include <stdio.h> /* Random thing to get __GNU_LIBRARY__. */
#if !defined _LIBC && defined __GNU_LIBRARY__ && __GNU_LIBRARY__ > 1
# include <gnu-versions.h>
# if (_GNU_OBSTACK_INTERFACE_VERSION == _OBSTACK_INTERFACE_VERSION \
|| (_GNU_OBSTACK_INTERFACE_VERSION == 1 \
&& _OBSTACK_INTERFACE_VERSION == 2 \
&& defined SIZEOF_INT && defined SIZEOF_SIZE_T \
&& SIZEOF_INT == SIZEOF_SIZE_T))
# define _OBSTACK_ELIDE_CODE
# if _GNU_OBSTACK_INTERFACE_VERSION == OBSTACK_INTERFACE_VERSION
# define ELIDE_CODE
# endif
#endif
#ifndef _OBSTACK_ELIDE_CODE
/* If GCC, or if an oddball (testing?) host that #defines __alignof__,
use the already-supplied __alignof__. Otherwise, this must be Gnulib
(as glibc assumes GCC); defer to Gnulib's alignof_type. */
# if !defined __GNUC__ && !defined __IBM__ALIGNOF__ && !defined __alignof__
# if defined __cplusplus
template <class type> struct alignof_helper { char __slot1; type __slot2; };
# define __alignof__(type) offsetof (alignof_helper<type>, __slot2)
# else
# define __alignof__(type) \
offsetof (struct { char __slot1; type __slot2; }, __slot2)
# endif
# endif
# include <stdlib.h>
#include <stddef.h>
#ifndef ELIDE_CODE
# include <stdint.h>
# ifndef MAX
# define MAX(a,b) ((a) > (b) ? (a) : (b))
# endif
/* Determine default alignment. */
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.
DEFAULT_ALIGNMENT cannot be an enum constant; see gnulib's alignof.h. */
#define DEFAULT_ALIGNMENT MAX (__alignof__ (long double), \
MAX (__alignof__ (uintmax_t), \
__alignof__ (void *)))
#define DEFAULT_ROUNDING MAX (sizeof (long double), \
MAX (sizeof (uintmax_t), \
sizeof (void *)))
/* Call functions with either the traditional malloc/free calling
interface, or the mmalloc/mfree interface (that adds an extra first
argument), based on the value of use_extra_arg. */
static void *
call_chunkfun (struct obstack *h, size_t size)
DEFAULT_ROUNDING. So we prepare for it to do that. */
enum
{
if (h->use_extra_arg)
return h->chunkfun.extra (h->extra_arg, size);
else
return h->chunkfun.plain (size);
}
DEFAULT_ALIGNMENT = offsetof (struct fooalign, u),
DEFAULT_ROUNDING = sizeof (union fooround)
};
static void
call_freefun (struct obstack *h, void *old_chunk)
{
if (h->use_extra_arg)
h->freefun.extra (h->extra_arg, old_chunk);
else
h->freefun.plain (old_chunk);
}
/* 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;
in such a case, redefine COPYING_UNIT to 'long' (if that works)
or 'char' as a last resort. */
# ifndef COPYING_UNIT
# define COPYING_UNIT int
# endif
/* The functions allocating more room by calling 'obstack_chunk_alloc'
jump to the handler pointed to by 'obstack_alloc_failed_handler'.
This can be set to a user defined function which should either
abort gracefully or use longjump - but shouldn't return. This
variable by default points to the internal function
'print_and_abort'. */
static _Noreturn void print_and_abort (void);
void (*obstack_alloc_failed_handler) (void) = print_and_abort;
/* Exit value used when 'print_and_abort' is used. */
# include <stdlib.h>
int obstack_exit_failure = EXIT_FAILURE;
# 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 = 0;
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
(that adds an extra first argument), based on the state of use_extra_arg.
For free, do not use ?:, since some compilers, like the MIPS compilers,
do not allow (expr) ? void : void. */
# 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) \
do { \
if ((h)->use_extra_arg) \
(*(h)->freefun)((h)->extra_arg, (old_chunk)); \
else \
(*(void (*)(void *))(h)->freefun)((old_chunk)); \
} while (0)
/* Initialize an obstack H for use. Specify chunk size SIZE (0 means default).
Objects start on multiples of ALIGNMENT (0 means use default).
CHUNKFUN is the function to use to allocate chunks,
and FREEFUN the function to free them.
Return nonzero if successful, calls obstack_alloc_failed_handler if
allocation fails. */
static int
_obstack_begin_worker (struct obstack *h,
_OBSTACK_SIZE_T size, _OBSTACK_SIZE_T alignment)
int
_obstack_begin (struct obstack *h,
int size, int alignment,
void *(*chunkfun) (long),
void (*freefun) (void *))
{
struct _obstack_chunk *chunk; /* points to new chunk */
@ -122,29 +149,32 @@ _obstack_begin_worker (struct obstack *h,
/* Default size is what GNU malloc can fit in a 4096-byte block. */
{
/* 12 is sizeof (mhead) and 4 is EXTRA from GNU malloc.
Use the values for range checking, because if range checking is off,
the extra bytes won't be missed terribly, but if range checking is on
and we used a larger request, a whole extra 4096 bytes would be
allocated.
Use the values for range checking, because if range checking is off,
the extra bytes won't be missed terribly, but if range checking is on
and we used a larger request, a whole extra 4096 bytes would be
allocated.
These number are irrelevant to the new GNU malloc. I suspect it is
less sensitive to the size of the request. */
These number are irrelevant to the new GNU malloc. I suspect it is
less sensitive to the size of the request. */
int extra = ((((12 + DEFAULT_ROUNDING - 1) & ~(DEFAULT_ROUNDING - 1))
+ 4 + DEFAULT_ROUNDING - 1)
& ~(DEFAULT_ROUNDING - 1));
+ 4 + DEFAULT_ROUNDING - 1)
& ~(DEFAULT_ROUNDING - 1));
size = 4096 - extra;
}
h->chunkfun = (struct _obstack_chunk * (*) (void *, long)) chunkfun;
h->freefun = (void (*) (void *, struct _obstack_chunk *)) freefun;
h->chunk_size = size;
h->alignment_mask = alignment - 1;
h->use_extra_arg = 0;
chunk = (struct _obstack_chunk *) call_chunkfun (h, h->chunk_size);
chunk = h->chunk = CALL_CHUNKFUN (h, h->chunk_size);
if (!chunk)
(*obstack_alloc_failed_handler) ();
h->chunk = chunk;
h->next_free = h->object_base = __PTR_ALIGN ((char *) chunk, chunk->contents,
alignment - 1);
h->chunk_limit = chunk->limit = (char *) chunk + h->chunk_size;
alignment - 1);
h->chunk_limit = chunk->limit
= (char *) chunk + h->chunk_size;
chunk->prev = 0;
/* The initial chunk now contains no empty object. */
h->maybe_empty_object = 0;
@ -153,29 +183,51 @@ _obstack_begin_worker (struct obstack *h,
}
int
_obstack_begin (struct obstack *h,
_OBSTACK_SIZE_T size, _OBSTACK_SIZE_T alignment,
void *(*chunkfun) (size_t),
void (*freefun) (void *))
_obstack_begin_1 (struct obstack *h, int size, int alignment,
void *(*chunkfun) (void *, long),
void (*freefun) (void *, void *),
void *arg)
{
h->chunkfun.plain = chunkfun;
h->freefun.plain = freefun;
h->use_extra_arg = 0;
return _obstack_begin_worker (h, size, alignment);
}
struct _obstack_chunk *chunk; /* points to new chunk */
int
_obstack_begin_1 (struct obstack *h,
_OBSTACK_SIZE_T size, _OBSTACK_SIZE_T alignment,
void *(*chunkfun) (void *, size_t),
void (*freefun) (void *, void *),
void *arg)
{
h->chunkfun.extra = chunkfun;
h->freefun.extra = freefun;
if (alignment == 0)
alignment = DEFAULT_ALIGNMENT;
if (size == 0)
/* Default size is what GNU malloc can fit in a 4096-byte block. */
{
/* 12 is sizeof (mhead) and 4 is EXTRA from GNU malloc.
Use the values for range checking, because if range checking is off,
the extra bytes won't be missed terribly, but if range checking is on
and we used a larger request, a whole extra 4096 bytes would be
allocated.
These number are irrelevant to the new GNU malloc. I suspect it is
less sensitive to the size of the request. */
int extra = ((((12 + DEFAULT_ROUNDING - 1) & ~(DEFAULT_ROUNDING - 1))
+ 4 + DEFAULT_ROUNDING - 1)
& ~(DEFAULT_ROUNDING - 1));
size = 4096 - extra;
}
h->chunkfun = (struct _obstack_chunk * (*)(void *,long)) chunkfun;
h->freefun = (void (*) (void *, struct _obstack_chunk *)) freefun;
h->chunk_size = size;
h->alignment_mask = alignment - 1;
h->extra_arg = arg;
h->use_extra_arg = 1;
return _obstack_begin_worker (h, size, alignment);
chunk = h->chunk = CALL_CHUNKFUN (h, h->chunk_size);
if (!chunk)
(*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;
/* The initial chunk now contains no empty object. */
h->maybe_empty_object = 0;
h->alloc_failed = 0;
return 1;
}
/* Allocate a new current chunk for the obstack *H
@ -185,25 +237,23 @@ _obstack_begin_1 (struct obstack *h,
to the beginning of the new one. */
void
_obstack_newchunk (struct obstack *h, _OBSTACK_SIZE_T length)
_obstack_newchunk (struct obstack *h, int length)
{
struct _obstack_chunk *old_chunk = h->chunk;
struct _obstack_chunk *new_chunk = 0;
size_t obj_size = h->next_free - h->object_base;
struct _obstack_chunk *new_chunk;
long new_size;
long obj_size = h->next_free - h->object_base;
long i;
long already;
char *object_base;
/* Compute size for new chunk. */
size_t sum1 = obj_size + length;
size_t sum2 = sum1 + h->alignment_mask;
size_t new_size = sum2 + (obj_size >> 3) + 100;
if (new_size < sum2)
new_size = sum2;
new_size = (obj_size + length) + (obj_size >> 3) + h->alignment_mask + 100;
if (new_size < h->chunk_size)
new_size = h->chunk_size;
/* Allocate and initialize the new chunk. */
if (obj_size <= sum1 && sum1 <= sum2)
new_chunk = (struct _obstack_chunk *) call_chunkfun (h, new_size);
new_chunk = CALL_CHUNKFUN (h, new_size);
if (!new_chunk)
(*obstack_alloc_failed_handler)();
h->chunk = new_chunk;
@ -214,19 +264,36 @@ _obstack_newchunk (struct obstack *h, _OBSTACK_SIZE_T length)
object_base =
__PTR_ALIGN ((char *) new_chunk, new_chunk->contents, h->alignment_mask);
/* Move the existing object to the new chunk. */
memcpy (object_base, h->object_base, obj_size);
/* Move the existing object to the new chunk.
Word at a time is fast and is safe if the object
is sufficiently aligned. */
if (h->alignment_mask + 1 >= DEFAULT_ALIGNMENT)
{
for (i = obj_size / sizeof (COPYING_UNIT) - 1;
i >= 0; i--)
((COPYING_UNIT *) object_base)[i]
= ((COPYING_UNIT *) h->object_base)[i];
/* We used to copy the odd few remaining bytes as one extra COPYING_UNIT,
but that can cross a page boundary on a machine
which does not do strict alignment for COPYING_UNITS. */
already = obj_size / sizeof (COPYING_UNIT) * sizeof (COPYING_UNIT);
}
else
already = 0;
/* Copy remaining bytes one by one. */
for (i = already; i < obj_size; i++)
object_base[i] = h->object_base[i];
/* 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->maybe_empty_object
&& (h->object_base
== __PTR_ALIGN ((char *) old_chunk, old_chunk->contents,
h->alignment_mask)))
== __PTR_ALIGN ((char *) old_chunk, old_chunk->contents,
h->alignment_mask)))
{
new_chunk->prev = old_chunk->prev;
call_freefun (h, old_chunk);
CALL_FREEFUN (h, old_chunk);
}
h->object_base = object_base;
@ -234,6 +301,9 @@ _obstack_newchunk (struct obstack *h, _OBSTACK_SIZE_T 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.
@ -264,8 +334,10 @@ _obstack_allocated_p (struct obstack *h, void *obj)
/* Free objects in obstack H, including OBJ and everything allocate
more recently than OBJ. If OBJ is zero, free everything in H. */
# undef obstack_free
void
_obstack_free (struct obstack *h, void *obj)
__obstack_free (struct obstack *h, void *obj)
{
struct _obstack_chunk *lp; /* below addr of any objects in this chunk */
struct _obstack_chunk *plp; /* point to previous chunk if any */
@ -277,10 +349,10 @@ _obstack_free (struct obstack *h, void *obj)
while (lp != 0 && ((void *) lp >= obj || (void *) (lp)->limit < obj))
{
plp = lp->prev;
call_freefun (h, lp);
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. */
chunk contains an empty object, so assume that it may. */
h->maybe_empty_object = 1;
}
if (lp)
@ -294,13 +366,17 @@ _obstack_free (struct obstack *h, void *obj)
abort ();
}
extern __typeof(_obstack_free) obstack_free __attribute__((alias("_obstack_free")));
# 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
_OBSTACK_SIZE_T
int
_obstack_memory_used (struct obstack *h)
{
struct _obstack_chunk *lp;
_OBSTACK_SIZE_T nbytes = 0;
int nbytes = 0;
for (lp = h->chunk; lp != 0; lp = lp->prev)
{
@ -309,20 +385,6 @@ _obstack_memory_used (struct obstack *h)
return nbytes;
}
# ifndef _OBSTACK_NO_ERROR_HANDLER
/* Define the error handler. */
# include <stdio.h>
/* Exit value used when 'print_and_abort' is used. */
# ifdef _LIBC
int obstack_exit_failure = EXIT_FAILURE;
# else
# ifndef EXIT_FAILURE
# define EXIT_FAILURE 1
# endif
# define obstack_exit_failure EXIT_FAILURE
# endif
# if defined _LIBC || (HAVE_LIBINTL_H && ENABLE_NLS)
# include <libintl.h>
# ifndef _
@ -334,22 +396,9 @@ int obstack_exit_failure = EXIT_FAILURE;
# endif
# endif
# if !(defined _Noreturn \
|| (defined __STDC_VERSION__ && __STDC_VERSION__ >= 201112))
# if ((defined __GNUC__ \
&& (__GNUC__ >= 3 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 8))) \
|| (defined __SUNPRO_C && __SUNPRO_C >= 0x5110))
# define _Noreturn __attribute__ ((__noreturn__))
# elif defined _MSC_VER && _MSC_VER >= 1200
# define _Noreturn __declspec (noreturn)
# else
# define _Noreturn
# endif
# endif
# ifdef _LIBC
# include <libio/iolibio.h>
# endif
# ifdef _LIBC
# include <libio/iolibio.h>
# endif
static _Noreturn void
print_and_abort (void)
@ -359,20 +408,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. */
# ifdef _LIBC
# ifdef _LIBC
(void) __fxprintf (NULL, "%s\n", _("memory exhausted"));
# else
# else
fprintf (stderr, "%s\n", _("memory exhausted"));
# endif
# endif
exit (obstack_exit_failure);
}
/* The functions allocating more room by calling 'obstack_chunk_alloc'
jump to the handler pointed to by 'obstack_alloc_failed_handler'.
This can be set to a user defined function which should either
abort gracefully or use longjump - but shouldn't return. This
variable by default points to the internal function
'print_and_abort'. */
void (*obstack_alloc_failed_handler) (void) = print_and_abort;
# endif /* !_OBSTACK_NO_ERROR_HANDLER */
#endif /* !_OBSTACK_ELIDE_CODE */
#endif /* !ELIDE_CODE */

323
obstack.h
View file

@ -1,5 +1,5 @@
/* obstack.h - object stack macros
Copyright (C) 1988-2020 Free Software Foundation, Inc.
Copyright (C) 1988-2023 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
@ -14,7 +14,7 @@
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
<https://www.gnu.org/licenses/>. */
/* Summary:
@ -85,17 +85,17 @@
break the ordinary 'growth' macro.
Summary:
We allocate large chunks.
We carve out one object at a time from the current chunk.
Once carved, an object never moves.
We are free to append data of any size to the currently
growing object.
Exactly one object is growing in an obstack at any one time.
You can run one obstack per control block.
You may have as many control blocks as you dare.
Because of the way we do it, you can "unwind" an obstack
back to a previous state. (You may remove objects much
as you would with a stack.)
We allocate large chunks.
We carve out one object at a time from the current chunk.
Once carved, an object never moves.
We are free to append data of any size to the currently
growing object.
Exactly one object is growing in an obstack at any one time.
You can run one obstack per control block.
You may have as many control blocks as you dare.
Because of the way we do it, you can "unwind" an obstack
back to a previous state. (You may remove objects much
as you would with a stack.)
*/
@ -104,24 +104,16 @@
#ifndef _OBSTACK_H
#define _OBSTACK_H 1
#ifndef _OBSTACK_INTERFACE_VERSION
# define _OBSTACK_INTERFACE_VERSION 2
#endif
/* 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 <stddef.h>'s symbols. Otherwise, include <stddef.h>
and use ptrdiff_t. */
#include <stddef.h> /* For size_t and ptrdiff_t. */
#include <string.h> /* For __GNU_LIBRARY__, and memcpy. */
#if _OBSTACK_INTERFACE_VERSION == 1
/* For binary compatibility with obstack version 1, which used "int"
and "long" for these two types. */
# define _OBSTACK_SIZE_T unsigned int
# define _CHUNK_SIZE_T unsigned long
# define _OBSTACK_CAST(type, expr) ((type) (expr))
#ifdef __PTRDIFF_TYPE__
# define PTR_INT_TYPE __PTRDIFF_TYPE__
#else
/* Version 2 with sane types, especially for 64-bit hosts. */
# define _OBSTACK_SIZE_T size_t
# define _CHUNK_SIZE_T size_t
# define _OBSTACK_CAST(type, expr) (expr)
# include <stddef.h>
# define PTR_INT_TYPE ptrdiff_t
#endif
/* If B is the base of an object addressed by P, return the result of
@ -130,16 +122,18 @@
#define __BPTR_ALIGN(B, P, A) ((B) + (((P) - (B) + (A)) & ~(A)))
/* Similar to __BPTR_ALIGN (B, P, A), except optimize the common case
/* Similar 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 ptrdiff_t is narrower than a
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 (ptrdiff_t) < sizeof (void *) ? (B) : (char *) 0, \
P, A)
__BPTR_ALIGN (sizeof (PTR_INT_TYPE) < sizeof (void *) ? (B) : (char *) 0, \
P, A)
#include <string.h>
#ifndef __attribute_pure__
# if defined __GNUC_MINOR__ && __GNUC__ * 1000 + __GNUC_MINOR__ >= 2096
@ -162,57 +156,49 @@ struct _obstack_chunk /* Lives at front of each chunk. */
struct obstack /* control current object in current chunk */
{
_CHUNK_SIZE_T chunk_size; /* preferred size to allocate chunks in */
long chunk_size; /* preferred size to allocate chunks in */
struct _obstack_chunk *chunk; /* address of current struct obstack_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 */
union
{
_OBSTACK_SIZE_T i;
void *p;
PTR_INT_TYPE tempint;
void *tempptr;
} temp; /* Temporary for some macros. */
_OBSTACK_SIZE_T alignment_mask; /* Mask of alignment for each object. */
/* These prototypes vary based on 'use_extra_arg'. */
union
{
void *(*plain) (size_t);
void *(*extra) (void *, size_t);
} chunkfun;
union
{
void (*plain) (void *);
void (*extra) (void *, void *);
} freefun;
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,
but having prototypes here quiets -Wstrict-prototypes. */
struct _obstack_chunk *(*chunkfun) (void *, long);
void (*freefun) (void *, struct _obstack_chunk *);
void *extra_arg; /* first arg for chunk alloc/dealloc funcs */
unsigned use_extra_arg : 1; /* chunk alloc/dealloc funcs take extra arg */
unsigned maybe_empty_object : 1; /* There is a possibility that the current
chunk contains a zero-length object. This
prevents freeing the chunk if we allocate
a bigger chunk to replace it. */
chunk contains a zero-length object. This
prevents freeing the chunk if we allocate
a bigger chunk to replace it. */
unsigned alloc_failed : 1; /* No longer used, as we now call the failed
handler on error, but retained for binary
compatibility. */
handler on error, but retained for binary
compatibility. */
};
/* Declare the external functions we use; they are in obstack.c. */
extern void _obstack_newchunk (struct obstack *, _OBSTACK_SIZE_T);
extern void _obstack_free (struct obstack *, void *);
extern int _obstack_begin (struct obstack *,
_OBSTACK_SIZE_T, _OBSTACK_SIZE_T,
void *(*) (size_t), void (*) (void *));
extern int _obstack_begin_1 (struct obstack *,
_OBSTACK_SIZE_T, _OBSTACK_SIZE_T,
void *(*) (void *, size_t),
void (*) (void *, void *), void *);
extern _OBSTACK_SIZE_T _obstack_memory_used (struct obstack *)
__attribute_pure__;
extern void _obstack_newchunk (struct obstack *, int);
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 *) __attribute_pure__;
/* Declare obstack_printf; it's in obstack_printf.c. */
extern int obstack_printf(struct obstack *obstack, const char *__restrict fmt, ...);
/* The default name of the function for freeing a chunk is 'obstack_free',
but gnulib users can override this by defining '__obstack_free'. */
#ifndef __obstack_free
# define __obstack_free obstack_free
#endif
extern void __obstack_free (struct obstack *, void *);
/* Error handler called when 'obstack_chunk_alloc' failed to allocate
@ -236,7 +222,7 @@ extern int obstack_exit_failure;
/* Pointer to next byte not yet allocated in current chunk. */
#define obstack_next_free(h) ((void *) (h)->next_free)
#define obstack_next_free(h) ((h)->next_free)
/* Mask specifying low bits that should be clear in address of an object. */
@ -245,38 +231,38 @@ extern int obstack_exit_failure;
/* To prevent prototype warnings provide complete argument list. */
#define obstack_init(h) \
_obstack_begin ((h), 0, 0, \
_OBSTACK_CAST (void *(*) (size_t), obstack_chunk_alloc), \
_OBSTACK_CAST (void (*) (void *), obstack_chunk_free))
(void *(*)(long))obstack_chunk_alloc, \
(void (*)(void *))obstack_chunk_free)
#define obstack_begin(h, size) \
_obstack_begin ((h), (size), 0, \
_OBSTACK_CAST (void *(*) (size_t), obstack_chunk_alloc), \
_OBSTACK_CAST (void (*) (void *), obstack_chunk_free))
(void *(*)(long))obstack_chunk_alloc, \
(void (*)(void *))obstack_chunk_free)
#define obstack_specify_allocation(h, size, alignment, chunkfun, freefun) \
#define obstack_specify_allocation(h, size, alignment, chunkfun, freefun) \
_obstack_begin ((h), (size), (alignment), \
_OBSTACK_CAST (void *(*) (size_t), chunkfun), \
_OBSTACK_CAST (void (*) (void *), freefun))
(void *(*)(long))(chunkfun), \
(void (*)(void *))(freefun))
#define obstack_specify_allocation_with_arg(h, size, alignment, chunkfun, freefun, arg) \
_obstack_begin_1 ((h), (size), (alignment), \
_OBSTACK_CAST (void *(*) (void *, size_t), chunkfun), \
_OBSTACK_CAST (void (*) (void *, void *), freefun), arg)
(void *(*)(void *, long))(chunkfun), \
(void (*)(void *, void *))(freefun), (arg))
#define obstack_chunkfun(h, newchunkfun) \
((void) ((h)->chunkfun.extra = (void *(*) (void *, size_t)) (newchunkfun)))
#define obstack_chunkfun(h, newchunkfun) \
((h)->chunkfun = (struct _obstack_chunk *(*)(void *, long))(newchunkfun))
#define obstack_freefun(h, newfreefun) \
((void) ((h)->freefun.extra = (void *(*) (void *, void *)) (newfreefun)))
#define obstack_freefun(h, newfreefun) \
((h)->freefun = (void (*)(void *, struct _obstack_chunk *))(newfreefun))
#define obstack_1grow_fast(h, achar) ((void) (*((h)->next_free)++ = (achar)))
#define obstack_1grow_fast(h, achar) (*((h)->next_free)++ = (achar))
#define obstack_blank_fast(h, n) ((void) ((h)->next_free += (n)))
#define obstack_blank_fast(h, n) ((h)->next_free += (n))
#define obstack_memory_used(h) _obstack_memory_used (h)
#if defined __GNUC__
# if !defined __GNUC_MINOR__ || __GNUC__ * 1000 + __GNUC_MINOR__ < 2008
# if ! (2 < __GNUC__ + (8 <= __GNUC_MINOR__))
# define __extension__
# endif
@ -288,37 +274,35 @@ extern int obstack_exit_failure;
# define obstack_object_size(OBSTACK) \
__extension__ \
({ struct obstack const *__o = (OBSTACK); \
(_OBSTACK_SIZE_T) (__o->next_free - __o->object_base); })
(unsigned) (__o->next_free - __o->object_base); })
/* The local variable is named __o1 to avoid a shadowed variable
warning when invoked from other obstack macros. */
# define obstack_room(OBSTACK) \
__extension__ \
({ struct obstack const *__o1 = (OBSTACK); \
(_OBSTACK_SIZE_T) (__o1->chunk_limit - __o1->next_free); })
({ struct obstack const *__o = (OBSTACK); \
(unsigned) (__o->chunk_limit - __o->next_free); })
# define obstack_make_room(OBSTACK, length) \
__extension__ \
({ struct obstack *__o = (OBSTACK); \
_OBSTACK_SIZE_T __len = (length); \
if (obstack_room (__o) < __len) \
_obstack_newchunk (__o, __len); \
int __len = (length); \
if (__o->chunk_limit - __o->next_free < __len) \
_obstack_newchunk (__o, __len); \
(void) 0; })
# define obstack_empty_p(OBSTACK) \
__extension__ \
({ struct obstack const *__o = (OBSTACK); \
(__o->chunk->prev == 0 \
&& __o->next_free == __PTR_ALIGN ((char *) __o->chunk, \
__o->chunk->contents, \
__o->alignment_mask)); })
&& __o->next_free == __PTR_ALIGN ((char *) __o->chunk, \
__o->chunk->contents, \
__o->alignment_mask)); })
# define obstack_grow(OBSTACK, where, length) \
__extension__ \
({ struct obstack *__o = (OBSTACK); \
_OBSTACK_SIZE_T __len = (length); \
if (obstack_room (__o) < __len) \
_obstack_newchunk (__o, __len); \
int __len = (length); \
if (__o->next_free + __len > __o->chunk_limit) \
_obstack_newchunk (__o, __len); \
memcpy (__o->next_free, where, __len); \
__o->next_free += __len; \
(void) 0; })
@ -326,9 +310,9 @@ extern int obstack_exit_failure;
# define obstack_grow0(OBSTACK, where, length) \
__extension__ \
({ struct obstack *__o = (OBSTACK); \
_OBSTACK_SIZE_T __len = (length); \
if (obstack_room (__o) < __len + 1) \
_obstack_newchunk (__o, __len + 1); \
int __len = (length); \
if (__o->next_free + __len + 1 > __o->chunk_limit) \
_obstack_newchunk (__o, __len + 1); \
memcpy (__o->next_free, where, __len); \
__o->next_free += __len; \
*(__o->next_free)++ = 0; \
@ -337,9 +321,10 @@ extern int obstack_exit_failure;
# define obstack_1grow(OBSTACK, datum) \
__extension__ \
({ struct obstack *__o = (OBSTACK); \
if (obstack_room (__o) < 1) \
_obstack_newchunk (__o, 1); \
obstack_1grow_fast (__o, datum); })
if (__o->next_free + 1 > __o->chunk_limit) \
_obstack_newchunk (__o, 1); \
obstack_1grow_fast (__o, datum); \
(void) 0; })
/* These assume that the obstack alignment is good enough for pointers
or ints, and that the data added so far to the current object
@ -348,15 +333,15 @@ extern int obstack_exit_failure;
# define obstack_ptr_grow(OBSTACK, datum) \
__extension__ \
({ struct obstack *__o = (OBSTACK); \
if (obstack_room (__o) < sizeof (void *)) \
_obstack_newchunk (__o, sizeof (void *)); \
obstack_ptr_grow_fast (__o, datum); })
if (__o->next_free + sizeof (void *) > __o->chunk_limit) \
_obstack_newchunk (__o, sizeof (void *)); \
obstack_ptr_grow_fast (__o, datum); }) \
# define obstack_int_grow(OBSTACK, datum) \
__extension__ \
({ struct obstack *__o = (OBSTACK); \
if (obstack_room (__o) < sizeof (int)) \
_obstack_newchunk (__o, sizeof (int)); \
if (__o->next_free + sizeof (int) > __o->chunk_limit) \
_obstack_newchunk (__o, sizeof (int)); \
obstack_int_grow_fast (__o, datum); })
# define obstack_ptr_grow_fast(OBSTACK, aptr) \
@ -378,10 +363,11 @@ extern int obstack_exit_failure;
# define obstack_blank(OBSTACK, length) \
__extension__ \
({ struct obstack *__o = (OBSTACK); \
_OBSTACK_SIZE_T __len = (length); \
if (obstack_room (__o) < __len) \
_obstack_newchunk (__o, __len); \
obstack_blank_fast (__o, __len); })
int __len = (length); \
if (__o->chunk_limit - __o->next_free < __len) \
_obstack_newchunk (__o, __len); \
obstack_blank_fast (__o, __len); \
(void) 0; })
# define obstack_alloc(OBSTACK, length) \
__extension__ \
@ -401,45 +387,44 @@ extern int obstack_exit_failure;
obstack_grow0 (__h, (where), (length)); \
obstack_finish (__h); })
/* The local variable is named __o1 to avoid a shadowed variable
warning when invoked from other obstack macros, typically obstack_free. */
/* The local variable is named __o1 to avoid a name conflict
when obstack_blank is called. */
# define obstack_finish(OBSTACK) \
__extension__ \
({ struct obstack *__o1 = (OBSTACK); \
void *__value = (void *) __o1->object_base; \
if (__o1->next_free == __value) \
__o1->maybe_empty_object = 1; \
__o1->maybe_empty_object = 1; \
__o1->next_free \
= __PTR_ALIGN (__o1->object_base, __o1->next_free, \
__o1->alignment_mask); \
if ((size_t) (__o1->next_free - (char *) __o1->chunk) \
> (size_t) (__o1->chunk_limit - (char *) __o1->chunk)) \
__o1->next_free = __o1->chunk_limit; \
= __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; })
# define obstack_free(OBSTACK, OBJ) \
__extension__ \
({ struct obstack *__o = (OBSTACK); \
void *__obj = (void *) (OBJ); \
void *__obj = (OBJ); \
if (__obj > (void *) __o->chunk && __obj < (void *) __o->chunk_limit) \
__o->next_free = __o->object_base = (char *) __obj; \
else \
_obstack_free (__o, __obj); })
__o->next_free = __o->object_base = (char *) __obj; \
else (__obstack_free) (__o, __obj); })
#else /* not __GNUC__ */
# define obstack_object_size(h) \
((_OBSTACK_SIZE_T) ((h)->next_free - (h)->object_base))
# define obstack_object_size(h) \
(unsigned) ((h)->next_free - (h)->object_base)
# define obstack_room(h) \
((_OBSTACK_SIZE_T) ((h)->chunk_limit - (h)->next_free))
(unsigned) ((h)->chunk_limit - (h)->next_free)
# define obstack_empty_p(h) \
# define obstack_empty_p(h) \
((h)->chunk->prev == 0 \
&& (h)->next_free == __PTR_ALIGN ((char *) (h)->chunk, \
(h)->chunk->contents, \
(h)->alignment_mask))
(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,56 +433,51 @@ extern int obstack_exit_failure;
but some compilers won't accept it. */
# define obstack_make_room(h, length) \
((h)->temp.i = (length), \
((obstack_room (h) < (h)->temp.i) \
? (_obstack_newchunk (h, (h)->temp.i), 0) : 0), \
(void) 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.i = (length), \
((obstack_room (h) < (h)->temp.i) \
? (_obstack_newchunk ((h), (h)->temp.i), 0) : 0), \
memcpy ((h)->next_free, where, (h)->temp.i), \
(h)->next_free += (h)->temp.i, \
(void) 0)
((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.i = (length), \
((obstack_room (h) < (h)->temp.i + 1) \
? (_obstack_newchunk ((h), (h)->temp.i + 1), 0) : 0), \
memcpy ((h)->next_free, where, (h)->temp.i), \
(h)->next_free += (h)->temp.i, \
*((h)->next_free)++ = 0, \
(void) 0)
((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) \
(((obstack_room (h) < 1) \
((((h)->next_free + 1 > (h)->chunk_limit) \
? (_obstack_newchunk ((h), 1), 0) : 0), \
obstack_1grow_fast (h, datum))
# define obstack_ptr_grow(h, datum) \
(((obstack_room (h) < sizeof (char *)) \
((((h)->next_free + sizeof (char *) > (h)->chunk_limit) \
? (_obstack_newchunk ((h), sizeof (char *)), 0) : 0), \
obstack_ptr_grow_fast (h, datum))
# define obstack_int_grow(h, datum) \
(((obstack_room (h) < sizeof (int)) \
((((h)->next_free + sizeof (int) > (h)->chunk_limit) \
? (_obstack_newchunk ((h), sizeof (int)), 0) : 0), \
obstack_int_grow_fast (h, datum))
# define obstack_ptr_grow_fast(h, aptr) \
(((const void **) ((h)->next_free += sizeof (void *)))[-1] = (aptr), \
(void) 0)
(((const void **) ((h)->next_free += sizeof (void *)))[-1] = (aptr))
# define obstack_int_grow_fast(h, aint) \
(((int *) ((h)->next_free += sizeof (int)))[-1] = (aint), \
(void) 0)
(((int *) ((h)->next_free += sizeof (int)))[-1] = (aint))
# define obstack_blank(h, length) \
((h)->temp.i = (length), \
((obstack_room (h) < (h)->temp.i) \
? (_obstack_newchunk ((h), (h)->temp.i), 0) : 0), \
obstack_blank_fast (h, (h)->temp.i))
((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)))
@ -512,22 +492,23 @@ extern int obstack_exit_failure;
(((h)->next_free == (h)->object_base \
? (((h)->maybe_empty_object = 1), 0) \
: 0), \
(h)->temp.p = (h)->object_base, \
(h)->temp.tempptr = (h)->object_base, \
(h)->next_free \
= __PTR_ALIGN ((h)->object_base, (h)->next_free, \
(h)->alignment_mask), \
(((size_t) ((h)->next_free - (char *) (h)->chunk) \
> (size_t) ((h)->chunk_limit - (char *) (h)->chunk)) \
(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, \
(h)->temp.p)
(h)->temp.tempptr)
# define obstack_free(h, obj) \
((h)->temp.p = (void *) (obj), \
(((h)->temp.p > (void *) (h)->chunk \
&& (h)->temp.p < (void *) (h)->chunk_limit) \
? (void) ((h)->next_free = (h)->object_base = (char *) (h)->temp.p) \
: _obstack_free ((h), (h)->temp.p)))
((h)->temp.tempint = (char *) (obj) - (char *) (h)->chunk, \
((((h)->temp.tempint > 0 \
&& (h)->temp.tempint < (h)->chunk_limit - (char *) (h)->chunk)) \
? (void) ((h)->next_free = (h)->object_base \
= (h)->temp.tempint + (char *) (h)->chunk) \
: (__obstack_free) (h, (h)->temp.tempint + (char *) (h)->chunk)))
#endif /* not __GNUC__ */
@ -535,4 +516,4 @@ extern int obstack_exit_failure;
} /* C++ */
#endif
#endif /* _OBSTACK_H */
#endif /* obstack.h */