Hi Collin,

> > That glibc patch needs more work, as I think Gnulib is misusing _LIBC.
> > _LIBC means we're using the header while compiling glibc itself,
> > whereas obstack.h appears in /usr/include/obstack.h and is used in
> > other contexts.
> 
> I see.
> 
> In lib/cdefs.h there is '#ifndef __GNULIB_CDEFS' and in lib/glob.in.h
> there is '# define __GLOB_GNULIB 1'.
> 
> Not the most elegant thing in the world, but perhaps gnulib-common.m4
> could '#define __GNULIB 1' in config.h and that can be used. That is the
> best idea that comes to mind at the moment.

This would be one possibility.

> The other idea I had was using _GL_ATTRIBUTE_PURE to detect Gnulib. Both
> glibc and Gnulib have:
> 
>     #ifndef __attribute_pure__
>     # define __attribute_pure__ _GL_ATTRIBUTE_PURE
>     #endif
> 
> So you could do:
> 
>     #ifndef _GL_ATTRIBUTE_PURE
>     # define __SMALL_PTRDIFF_T 0
>     #endif

This sounds like a hack; better avoid that.

But before inventing a new mechanism, maybe there is already an existing one?
Look at
  modules/error-h
  modules/fnmatch-h
  modules/getopt-posix
  modules/glob-h
  modules/ieee754-h
These are the modules that provide a header very similar to the glibc one.

modules/getopt-posix and modules/glob-h mirror the glibc file under a different
name than lib/<xxx>.in.h; then lib/<xxx>.in.h can #include that file. This is
the most general solution. It comes at the cost of another .h file.

modules/ieee754-h is simpler, with a use of _GL_GNULIB_HEADER that is
effectively replaced with 1 on the gnulib side. But this works only if
there are no other substitutions to be made (no @...@ replacements)
in preprocessor lines. (I would not bet that code like this:
  #if 0
  # if @FOOBAR@
  # endif
  #endif
works for all C and C++ compilers. Better avoid that.)

In any case, the ieee754-h approach is not to think "let's look at the
gnulib .in.h file and see how we can adapt it for glibc" but instead
"let's create a well-formed .h file for glibc and then let's see how we
can massage it so that it works with gnulib".

The latter approach leads me to the following patch (that should work
when the header is installed in /usr/include and even with "gcc -Wundef"):


2025-04-30  Bruno Haible  <br...@clisp.org>

        obstack: Make it easier to sync back with glibc.
        * lib/obstack.in.h: Use __GL_GNULIB_HEADER to delimit sections that are
        for Gnulib usage.
        Test __GL_SMALL_PTRDIFF_T__ instead of @SMALL_PTRDIFF_T@.
        Test __GL_REPLACE_OBSTACK__ instead of @REPLACE_OBSTACK@.
        * modules/obstack (Makefile.am): Substitute __GL_GNULIB_HEADER.
        Substitute __GL_SMALL_PTRDIFF_T__ instead of @SMALL_PTRDIFF_T@.
        Substitute __GL_REPLACE_OBSTACK__ instead of @REPLACE_OBSTACK@.

diff --git a/lib/obstack.in.h b/lib/obstack.in.h
index b5791ee294..39eb3a030f 100644
--- a/lib/obstack.in.h
+++ b/lib/obstack.in.h
@@ -105,9 +105,12 @@
 #ifndef _OBSTACK_H
 #define _OBSTACK_H 1
 
-/* This file uses _Noreturn, _GL_ATTRIBUTE_PURE.  */
-#if !_GL_CONFIG_H_INCLUDED
- #error "Please include config.h first."
+#if defined __GL_GNULIB_HEADER
+/* Gnulib usage.  */
+/* This file uses _GL_ATTRIBUTE_PURE.  */
+# if !_GL_CONFIG_H_INCLUDED
+  #error "Please include config.h first."
+# endif
 #endif
 
 #include <stddef.h>             /* For size_t and ptrdiff_t.  */
@@ -122,15 +125,16 @@
 
 /* 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
+#if defined __GL_GNULIB_HEADER
 /* 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)
+#else
+/* glibc usage.  */
+# define _OBSTACK_SIZE_T unsigned int
+# define _CHUNK_SIZE_T unsigned long
+# define _OBSTACK_CAST(type, expr) ((type) (expr))
 #endif
 
 /* __PTR_ALIGN(B, P, A) returns the result of aligning P to the next multiple
@@ -139,7 +143,7 @@
    If ptrdiff_t 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 through uintptr_t.  */
-#if @SMALL_PTRDIFF_T@
+#if defined __GL_SMALL_PTRDIFF_T__
 # define __PTR_ALIGN(B, P, A) \
    ((B) + (((P) - (B) + (A)) & ~(A)))
 #else
@@ -210,7 +214,7 @@ struct obstack          /* control current object in 
current chunk */
 
 /* Declare the external functions we use; they are in obstack.c.  */
 
-#if @REPLACE_OBSTACK@
+#if defined __GL_REPLACE_OBSTACK__
 # define _obstack_newchunk rpl_obstack_newchunk
 # define _obstack_free rpl_obstack_free
 # define _obstack_begin rpl_obstack_begin
diff --git a/modules/obstack b/modules/obstack
index 77b81f9e44..5065a693cc 100644
--- a/modules/obstack
+++ b/modules/obstack
@@ -31,8 +31,9 @@ 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' \
-             -e 's|@''SMALL_PTRDIFF_T''@|$(SMALL_PTRDIFF_T)|g' \
+             -e 's/defined __GL_GNULIB_HEADER/1/g' \
+             -e 's|defined __GL_REPLACE_OBSTACK__|$(REPLACE_OBSTACK)|g' \
+             -e 's|defined __GL_SMALL_PTRDIFF_T__|$(SMALL_PTRDIFF_T)|g' \
              $(srcdir)/obstack.in.h > $@-t
        $(AM_V_at)mv $@-t $@
 else




Reply via email to