From 5657476a730c6dc296c6d4a3ab239ba7ef339fad Mon Sep 17 00:00:00 2001 From: Bruno Haible Date: Thu, 16 Nov 2023 00:09:40 +0100 Subject: [PATCH] obstack: Modernize, fixing several problems. * lib/obstack.in.h: Renamed from lib/obstack.h. Add reference to the glibc documentation. (_OBSTACK_INTERFACE_VERSION): Remove macro. (_OBSTACK_SIZE_T, _CHUNK_SIZE_T, _OBSTACK_CAST): Mark old values with _LIBC. (_obstack_newchunk, _obstack_free, _obstack_begin, _obstack_begin_1, _obstack_memory_used, _obstack_allocated_p): Override if REPLACE_OBSTACK is 1. * lib/obstack.c: Don't include . (_OBSTACK_ELIDE_CODE): Remove macro. * m4/obstack.m4 (gl_FUNC_OBSTACK): Test whether obstack.h exists. Don't define HAVE_OBSTACK any more. Set HAVE_OBSTACK, REPLACE_OBSTACK, GL_GENERATE_OBSTACK_H. * modules/obstack (Files): Remove obstack.h. Add obstack.in.h. (Depends-on): Add gen-header. Add conditions. (configure.ac): Consider HAVE_OBSTACK, REPLACE_OBSTACK. Invoke gl_CONDITIONAL_HEADER and AC_PROG_MKDIR_P. (Makefile.am): Generate obstack.h. Augment BUILT_SOURCES and MOSTLYCLEANFILES. --- ChangeLog | 23 +++++++++ lib/obstack.c | 91 +++++++++++++-------------------- lib/{obstack.h => obstack.in.h} | 26 ++++++---- m4/obstack.m4 | 53 ++++++++++++------- modules/obstack | 35 ++++++++++--- 5 files changed, 136 insertions(+), 92 deletions(-) rename lib/{obstack.h => obstack.in.h} (97%) diff --git a/ChangeLog b/ChangeLog index 16dbb4240c..9132fef875 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,26 @@ +2023-11-15 Bruno Haible + + obstack: Modernize, fixing several problems. + * lib/obstack.in.h: Renamed from lib/obstack.h. Add reference to the + glibc documentation. + (_OBSTACK_INTERFACE_VERSION): Remove macro. + (_OBSTACK_SIZE_T, _CHUNK_SIZE_T, _OBSTACK_CAST): Mark old values with + _LIBC. + (_obstack_newchunk, _obstack_free, _obstack_begin, _obstack_begin_1, + _obstack_memory_used, _obstack_allocated_p): Override if REPLACE_OBSTACK + is 1. + * lib/obstack.c: Don't include . + (_OBSTACK_ELIDE_CODE): Remove macro. + * m4/obstack.m4 (gl_FUNC_OBSTACK): Test whether obstack.h exists. Don't + define HAVE_OBSTACK any more. Set HAVE_OBSTACK, REPLACE_OBSTACK, + GL_GENERATE_OBSTACK_H. + * modules/obstack (Files): Remove obstack.h. Add obstack.in.h. + (Depends-on): Add gen-header. Add conditions. + (configure.ac): Consider HAVE_OBSTACK, REPLACE_OBSTACK. Invoke + gl_CONDITIONAL_HEADER and AC_PROG_MKDIR_P. + (Makefile.am): Generate obstack.h. Augment BUILT_SOURCES and + MOSTLYCLEANFILES. + 2023-11-15 Paul Eggert striconveha: pacify gcc -Wcast-align diff --git a/lib/obstack.c b/lib/obstack.c index ca2e61c8cc..99cee94ede 100644 --- a/lib/obstack.c +++ b/lib/obstack.c @@ -23,43 +23,23 @@ # include "obstack.h" #endif -/* NOTE BEFORE MODIFYING THIS FILE: _OBSTACK_INTERFACE_VERSION in - obstack.h must be incremented whenever callers compiled using an old +/* NOTE BEFORE MODIFYING THIS FILE IN GNU LIBC: _OBSTACK_INTERFACE_VERSION in + gnu-versions.h must be incremented whenever callers compiled using an old obstack.h can no longer properly call the functions in this file. */ -/* 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 - supports the same library interface we do. This code is part of the GNU - C Library, but also included in many other GNU distributions. Compiling - and linking in this code is a waste when using the GNU C library - (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. */ -#if !defined _LIBC && defined __GNU_LIBRARY__ && __GNU_LIBRARY__ > 1 -# include -# 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 -# 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 __alignof__ -# include -# define __alignof__(type) alignof_type (type) -# endif -# include -# include +#if !defined __GNUC__ && !defined __alignof__ +# include +# define __alignof__(type) alignof_type (type) +#endif +#include +#include -# ifndef MAX -# define MAX(a,b) ((a) > (b) ? (a) : (b)) -# endif +#ifndef MAX +# define MAX(a,b) ((a) > (b) ? (a) : (b)) +#endif /* Determine default alignment. */ @@ -300,30 +280,30 @@ _obstack_memory_used (struct obstack *h) return nbytes; } -# ifndef _OBSTACK_NO_ERROR_HANDLER +#ifndef _OBSTACK_NO_ERROR_HANDLER /* Define the error handler. */ -# include +# include /* Exit value used when 'print_and_abort' is used. */ -# ifdef _LIBC +# ifdef _LIBC int obstack_exit_failure = EXIT_FAILURE; -# else -# include "exitfail.h" -# define obstack_exit_failure exit_failure -# endif - -# ifdef _LIBC -# include -# else -# include "gettext.h" -# endif -# ifndef _ -# define _(msgid) gettext (msgid) -# endif - -# ifdef _LIBC -# include -# endif +# else +# include "exitfail.h" +# define obstack_exit_failure exit_failure +# endif + +# ifdef _LIBC +# include +# else +# include "gettext.h" +# endif +# ifndef _ +# define _(msgid) gettext (msgid) +# endif + +# ifdef _LIBC +# include +# endif static __attribute_noreturn__ void print_and_abort (void) @@ -333,11 +313,11 @@ 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); } @@ -349,5 +329,4 @@ print_and_abort (void) 'print_and_abort'. */ __attribute_noreturn__ void (*obstack_alloc_failed_handler) (void) = print_and_abort; -# endif /* !_OBSTACK_NO_ERROR_HANDLER */ -#endif /* !_OBSTACK_ELIDE_CODE */ +#endif /* !_OBSTACK_NO_ERROR_HANDLER */ diff --git a/lib/obstack.h b/lib/obstack.in.h similarity index 97% rename from lib/obstack.h rename to lib/obstack.in.h index cb080c33b5..265203b6e2 100644 --- a/lib/obstack.h +++ b/lib/obstack.in.h @@ -97,9 +97,11 @@ as you would with a stack.) */ +/* Documentation (part of the GNU libc manual): + */ -/* Don't do the contents of this file more than once. */ +/* Don't do the contents of this file more than once. */ #ifndef _OBSTACK_H #define _OBSTACK_H 1 @@ -108,12 +110,8 @@ #error "Please include config.h first." #endif -#ifndef _OBSTACK_INTERFACE_VERSION -# define _OBSTACK_INTERFACE_VERSION 2 -#endif - #include /* For size_t and ptrdiff_t. */ -#include /* For __GNU_LIBRARY__, and memcpy. */ +#include /* For memcpy. */ #if __STDC_VERSION__ < 199901L || defined __HP_cc # define __FLEXIBLE_ARRAY_MEMBER 1 @@ -121,14 +119,14 @@ # define __FLEXIBLE_ARRAY_MEMBER #endif -#if _OBSTACK_INTERFACE_VERSION == 1 -/* For binary compatibility with obstack version 1, which used "int" - and "long" for these two types. */ +/* These macros highlight the places where this implementation + is different from the one in GNU libc. */ +#ifdef _LIBC # define _OBSTACK_SIZE_T unsigned int # define _CHUNK_SIZE_T unsigned long # define _OBSTACK_CAST(type, expr) ((type) (expr)) #else -/* Version 2 with sane types, especially for 64-bit hosts. */ +/* In Gnulib, we use 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) @@ -214,6 +212,14 @@ struct obstack /* control current object in current chunk */ /* Declare the external functions we use; they are in obstack.c. */ +#if @REPLACE_OBSTACK@ +# define _obstack_newchunk rpl_obstack_newchunk +# define _obstack_free rpl_obstack_free +# define _obstack_begin rpl_obstack_begin +# define _obstack_begin_1 rpl_obstack_begin_1 +# define _obstack_memory_used rpl_obstack_memory_used +# define _obstack_allocated_p rpl_obstack_allocated_p +#endif extern void _obstack_newchunk (struct obstack *, _OBSTACK_SIZE_T); extern void _obstack_free (struct obstack *, void *); extern int _obstack_begin (struct obstack *, diff --git a/m4/obstack.m4 b/m4/obstack.m4 index ef70a52093..88a3f3a0e0 100644 --- a/m4/obstack.m4 +++ b/m4/obstack.m4 @@ -10,24 +10,39 @@ dnl We provide our own macro here. AC_DEFUN([gl_FUNC_OBSTACK], [ - AC_CACHE_CHECK([for obstacks that work with any size object], - [gl_cv_func_obstack], - [AC_LINK_IFELSE( - [AC_LANG_PROGRAM( - [[#include "obstack.h" - void *obstack_chunk_alloc (size_t n) { return 0; } - void obstack_chunk_free (void *p) { } - /* Check that an internal function returns size_t, not int. */ - size_t _obstack_memory_used (struct obstack *); - ]], - [[struct obstack mem; - obstack_init (&mem); - obstack_free (&mem, 0); - ]])], - [gl_cv_func_obstack=yes], - [gl_cv_func_obstack=no])]) - if test "$gl_cv_func_obstack" = yes; then - AC_DEFINE([HAVE_OBSTACK], 1, - [Define to 1 if the system has obstacks that work with any size object.]) + AC_CHECK_HEADERS_ONCE([obstack.h]) + if test $ac_cv_header_obstack_h = yes; then + HAVE_OBSTACK=1 + AC_CACHE_CHECK([for obstacks that work with any size object], + [gl_cv_func_obstack], + [AC_LINK_IFELSE( + [AC_LANG_PROGRAM( + [[#include "obstack.h" + void *obstack_chunk_alloc (size_t n) { return 0; } + void obstack_chunk_free (void *p) { } + /* Check that an internal function returns size_t, not int. */ + size_t _obstack_memory_used (struct obstack *); + ]], + [[struct obstack mem; + obstack_init (&mem); + obstack_free (&mem, 0); + ]])], + [gl_cv_func_obstack=yes], + [gl_cv_func_obstack=no]) + ]) + if test $gl_cv_func_obstack = yes; then + REPLACE_OBSTACK=0 + else + REPLACE_OBSTACK=1 + fi + else + HAVE_OBSTACK=0 + REPLACE_OBSTACK=0 fi + if test $HAVE_OBSTACK = 0 || test $REPLACE_OBSTACK = 1; then + GL_GENERATE_OBSTACK_H=true + else + GL_GENERATE_OBSTACK_H=false + fi + AC_SUBST([REPLACE_OBSTACK]) ]) diff --git a/modules/obstack b/modules/obstack index 98bca67e1e..e4db4cdc97 100644 --- a/modules/obstack +++ b/modules/obstack @@ -2,22 +2,43 @@ Description: Memory allocation, optimized for stack-like allocation patterns. Files: -lib/obstack.h +lib/obstack.in.h lib/obstack.c m4/obstack.m4 Depends-on: -alignof -gettext-h -exitfail -stdint -stdlib +gen-header +alignof [test $HAVE_OBSTACK = 0 || test $REPLACE_OBSTACK = 1] +gettext-h [test $HAVE_OBSTACK = 0 || test $REPLACE_OBSTACK = 1] +exitfail [test $HAVE_OBSTACK = 0 || test $REPLACE_OBSTACK = 1] +stdint [test $HAVE_OBSTACK = 0 || test $REPLACE_OBSTACK = 1] +stdlib [test $HAVE_OBSTACK = 0 || test $REPLACE_OBSTACK = 1] configure.ac: gl_FUNC_OBSTACK -gl_CONDITIONAL([GL_COND_OBJ_OBSTACK], [test "$gl_cv_func_obstack" != yes]) +gl_CONDITIONAL_HEADER([obstack.h]) +gl_CONDITIONAL([GL_COND_OBJ_OBSTACK], + [test $HAVE_OBSTACK = 0 || test $REPLACE_OBSTACK = 1]) +AC_PROG_MKDIR_P Makefile.am: +BUILT_SOURCES += $(OBSTACK_H) + +# We need the following in order to create when the system +# doesn't have one that works with any size object. +if GL_GENERATE_OBSTACK_H +obstack.h: obstack.in.h $(top_builddir)/config.status +@NMD@ $(AM_V_GEN)$(MKDIR_P) '%reldir%' + $(gl_V_at)$(SED_HEADER_STDOUT) \ + -e 's|@''REPLACE_OBSTACK''@|$(REPLACE_OBSTACK)|g' \ + $(srcdir)/obstack.in.h > $@-t + $(AM_V_at)mv $@-t $@ +else +obstack.h: $(top_builddir)/config.status + rm -f $@ +endif +MOSTLYCLEANFILES += obstack.h obstack.h-t + if GL_COND_OBJ_OBSTACK lib_SOURCES += obstack.c endif -- 2.39.5