On 2024-08-07 02:58, Bruno Haible wrote:
Did it possibly embody the
assumption that errno values are small integers or all near together?

Yes it did. My preference for static checking went overboard, it seems. I installed the attached, which I hope fixes it.
From 37fcd9c9d822150f807211de0fec6c7d86de60ef Mon Sep 17 00:00:00 2001
From: Paul Eggert <egg...@cs.ucla.edu>
Date: Wed, 7 Aug 2024 07:23:51 -0700
Subject: [PATCH] errno-tests: port to GNU/Hurd

Test for errno distinctness dynamically rather than statically,
since the static test blows up the compiler on Hurd.
Problem reported by Bruno Haible in:
https://lists.gnu.org/r/bug-gnulib/2024-08/msg00039.html
Also, test that errno values can all be used in #if,
and improve diagnostics.
* tests/test-errno.c: Include stdio.h, stdlib.h, string.h.
(USABLE_IN_IF): New macro.  Use it to check errno values in #if.
(ERRTAB): New macro.
(struct nameval): New type.
(errtab): New global variable.
(errtab_cmp): New function.
(main): Test for errno distinctness dynamically not statically.
Diagnose lack of distinctness better.
---
 ChangeLog          | 18 +++++++++++++++
 tests/test-errno.c | 57 +++++++++++++++++++++++++++++++++++-----------
 2 files changed, 62 insertions(+), 13 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 8e0896f127..df710ddfa6 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,21 @@
+2024-08-07  Paul Eggert  <egg...@cs.ucla.edu>
+
+	errno-tests: port to GNU/Hurd
+	Test for errno distinctness dynamically rather than statically,
+	since the static test blows up the compiler on Hurd.
+	Problem reported by Bruno Haible in:
+	https://lists.gnu.org/r/bug-gnulib/2024-08/msg00039.html
+	Also, test that errno values can all be used in #if,
+	and improve diagnostics.
+	* tests/test-errno.c: Include stdio.h, stdlib.h, string.h.
+	(USABLE_IN_IF): New macro.  Use it to check errno values in #if.
+	(ERRTAB): New macro.
+	(struct nameval): New type.
+	(errtab): New global variable.
+	(errtab_cmp): New function.
+	(main): Test for errno distinctness dynamically not statically.
+	Diagnose lack of distinctness better.
+
 2024-08-07  Bruno Haible  <br...@clisp.org>
 
 	fchmodat: Fix cross-compilation guess.
diff --git a/tests/test-errno.c b/tests/test-errno.c
index 7403ee1432..acd07ab95b 100644
--- a/tests/test-errno.c
+++ b/tests/test-errno.c
@@ -20,6 +20,10 @@
 
 #include <errno.h>
 
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
 /* Check all POSIX-defined errno values, using M (v) to check value v.  */
 #define CHECK_POSIX_ERRNOS(m) \
   m (E2BIG) \
@@ -107,24 +111,51 @@
 #define POSITIVE_INTEGER_CONSTANT_EXPRESSION(e) static_assert (0 < (e) << 0);
 CHECK_POSIX_ERRNOS (POSITIVE_INTEGER_CONSTANT_EXPRESSION)
 
+/* Verify that errno values can all be used in #if.  */
+#define USABLE_IN_IF(e) ^ e
+#if 0 CHECK_POSIX_ERRNOS (USABLE_IN_IF)
+#endif
+
+/* Check that errno values all differ, except possibly for
+   EWOULDBLOCK == EAGAIN and ENOTSUP == EOPNOTSUPP.  */
+#define ERRTAB(e) { #e, e },
+static struct nameval { char const *name; int value; }
+  errtab[] = { CHECK_POSIX_ERRNOS (ERRTAB) };
+
+static int
+errtab_cmp (void const *va, void const *vb)
+{
+  struct nameval const *a = va, *b = vb;
+
+  /* Sort by value first, then by name (to simplify later tests).
+     Subtraction cannot overflow as both are positive.  */
+  int diff = a->value - b->value;
+  return diff ? diff : strcmp (a->name, b->name);
+}
+
 int
 main ()
 {
+  int test_exit_status = EXIT_SUCCESS;
+
   /* Verify that errno can be assigned.  */
   errno = EOVERFLOW;
 
   /* Check that errno values all differ, except possibly for
-     EWOULDBLOCK == EAGAIN and ENOTSUP == EOPNOTSUPP.  */
-  #define INDEXED_BY_ERRNO(e) [e] = 1,
-  #define ERRNO_COUNT(e) 0,
-  static char const
-    indexed_by_errno[] = { CHECK_POSIX_ERRNOS (INDEXED_BY_ERRNO) },
-    errno_count[] = { CHECK_POSIX_ERRNOS (ERRNO_COUNT) };
-  int distinct_errnos = 0;
-  for (int i = 0; i < sizeof indexed_by_errno; i++)
-    distinct_errnos += indexed_by_errno[i];
-  return ((sizeof errno_count
-           - (EWOULDBLOCK == EAGAIN)
-           - (ENOTSUP == EOPNOTSUPP))
-          != distinct_errnos);
+     EAGAIN == EWOULDBLOCK and ENOTSUP == EOPNOTSUPP.  */
+  int nerrtab = sizeof errtab / sizeof *errtab;
+  qsort (errtab, nerrtab, sizeof *errtab, errtab_cmp);
+  for (int i = 1; i < nerrtab; i++)
+    if (errtab[i - 1].value == errtab[i].value)
+      {
+        fprintf (stderr, "%s == %s == %d\n",
+                 errtab[i - 1].name, errtab[i].name, errtab[i].value);
+        if (! ((strcmp ("EAGAIN", errtab[i - 1].name) == 0
+                && strcmp ("EWOULDBLOCK", errtab[i].name) == 0)
+               || (strcmp ("ENOTSUP", errtab[i - 1].name) == 0
+                   && strcmp ("EOPNOTSUPP", errtab[i].name) == 0)))
+          test_exit_status = EXIT_FAILURE;
+      }
+
+  return test_exit_status;
 }
-- 
2.43.0

Reply via email to