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