This patch fixes the following test failure:

./test-emacs-1.out tmp52599-out differ: byte 37757, line 896
--- ./test-emacs-1.out  2024-03-24 03:30:48.285074696 -0700
+++ tmp52599-out        2024-03-25 02:01:39.966937097 -0700
@@ -893,6 +893,10 @@
 Finished.
 
 You may need to add #include directives for the following .h files.
+  # include <sys/socket.h>
+  # include <ws2tcpip.h>
+  #elif HAVE_WS2TCPIP_H
+  #endif
   #include <alloca.h>
   #include <byteswap.h>
   #include <dirent.h>
@@ -913,6 +917,7 @@
   #include <sys/select.h>
   #include <sys/stat.h>
   #include <sys/time.h>
+  #include <sys/types.h>
   #include <time.h>
   #include <unistd.h>
   #include "acl.h"
@@ -947,12 +952,7 @@
   #include "tempname.h"
   #include "timespec.h"
   #include "unlocked-io.h"
-  #include <sys/types.h>
   #if HAVE_SYS_SOCKET_H
-  # include <sys/socket.h>
-  #elif HAVE_WS2TCPIP_H
-  # include <ws2tcpip.h>
-  #endif

The comments above this section of code are *slightly* misleading, so
I can see how it was written the way it is in gnulib-tool.py:

  # First the #include <...> directives without #ifs, sorted for convenience,
  # then the #include "..." directives without #ifs, sorted for convenience,
  # then the #include directives that are surrounded by #ifs. Not sorted.

The incorrect behavior of gnulib-tool.py is because it processes each
'Include:' section line by line. The behavior of gnulib-tool.sh is to
first determine if the entire 'Include:' section contains #if's. If it
does than all lines are stored separately. If not all lines matching
'#include "*' are separated from those who don't.

I say that this is slightly misleading because #include <sys/types.h>
is after #include "..."'s even though it is not nested under an #if.

This is because of socklen and the actual process for sorting:

#include <sys/types.h>
#if HAVE_SYS_SOCKET_H
# include <sys/socket.h>
#elif HAVE_WS2TCPIP_H
# include <ws2tcpip.h>
#endif

Probably not worth changing the comment for that one exception though. :)

Collin
From d0fe63699d4c01b97e920e3c87b3dd95ffb52824 Mon Sep 17 00:00:00 2001
From: Collin Funk <collin.fu...@gmail.com>
Date: Mon, 25 Mar 2024 01:56:24 -0700
Subject: [PATCH 2/2] gnulib-tool.py: Fix output of #include directive advice.

* pygnulib/GLImport.py (GLImport.execute): Copy comment from
gnulib-tool.sh with modified variable names. Search the 'Include:' as a
whole instead of each individual line.
---
 ChangeLog            |  7 +++++++
 pygnulib/GLImport.py | 48 +++++++++++++++++++++++---------------------
 2 files changed, 32 insertions(+), 23 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index d699b692e3..4e2919baa9 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2024-03-25  Collin Funk  <collin.fu...@gmail.com>
+
+	gnulib-tool.py: Fix output of #include directive advice.
+	* pygnulib/GLImport.py (GLImport.execute): Copy comment from
+	gnulib-tool.sh with modified variable names. Search the 'Include:' as a
+	whole instead of each individual line.
+
 2024-03-24  Collin Funk  <collin.fu...@gmail.com>
 
 	gnulib-tool.py: Handle removed files in the vc ignore files.
diff --git a/pygnulib/GLImport.py b/pygnulib/GLImport.py
index 5b24d0fb88..2ac243c419 100644
--- a/pygnulib/GLImport.py
+++ b/pygnulib/GLImport.py
@@ -1432,34 +1432,36 @@ AC_DEFUN([%s_FILE_LIST], [\n''' % macro_prefix
         # Finish the work.
         print('Finished.\n')
         print('You may need to add #include directives for the following .h files.')
-        modules = sorted(set([ module
-                               for module in self.moduletable['base']
-                               if module in self.moduletable['main'] ]))
+        # Intersect 'base' modules and 'main' modules
+        # (since 'base' modules is not necessarily of subset of 'main' modules
+        # - some may have been skipped through --avoid, and since the elements of
+        # 'main' modules but not in 'base' modules can go away without explicit
+        # notice - through changes in the module dependencies).
+        modules = sorted(set(self.moduletable['base']).intersection(self.moduletable['main']))
         # First the #include <...> directives without #ifs, sorted for convenience,
         # then the #include "..." directives without #ifs, sorted for convenience,
         # then the #include directives that are surrounded by #ifs. Not sorted.
-        includes_angles = list()
-        includes_quotes = list()
-        includes_if = list()
+        include_angles = []
+        include_quotes = []
+        include_if = []
         for module in modules:
             include = module.getInclude()
-            for include in include.split('\n'):
-                if '%s#if' % constants.NL in '%s%s' % (constants.NL, include):
-                    includes_if += [include]
-                # if '%s#if' % constants.NL in '%s%s' % (constants.NL, include)
-                else:
-                    if 'include "' in include:
-                        includes_quotes += [include]
-                    else:  # if 'include "' not in include
-                        includes_angles += [include]
-        includes_angles = sorted(set(includes_angles))
-        includes_quotes = sorted(set(includes_quotes))
-        includes = includes_angles + includes_quotes + includes_if
-        includes = [ include
-                     for include in includes
-                     if include.split() ]
-        for include in includes:
-            print('  %s' % include)
+            if '\n#if' in include:
+                include_if += [ f'  {line}'
+                                for line in include.split('\n')
+                                if line.strip() ]
+            else:
+                include_angles += [ f'  {line}'
+                                    for line in include.split('\n')
+                                    if 'include "' not in line and line.strip() ]
+                include_quotes += [ f'  {line}'
+                                    for line in include.split('\n')
+                                    if 'include "' in line and line.strip() ]
+
+        includes = lines_to_multiline(sorted(set(include_angles)))
+        includes += lines_to_multiline(sorted(set(include_quotes)))
+        includes += lines_to_multiline(include_if)
+        print(includes, end='')
 
         # Get link directives.
         links = [ module.getLink()
-- 
2.44.0

Reply via email to