From 37fcd9c9d822150f807211de0fec6c7d86de60ef Mon Sep 17 00:00:00 2001 From: Paul Eggert 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 + + 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 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 +#include +#include +#include + /* 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