Re: configure output from largefile.m4

2024-06-18 Thread Bruno Haible
Paul Eggert wrote:
> Thanks, I installed the attached which I hope is good enough. It's also 
> in Autoconf master now.

Thanks!






Re: [PATCH 6/7] nstrftime, -0000

2024-06-18 Thread Bruno Haible
Paul Eggert wrote:
> > After the Solaris crash fix, the nstrftime tests still fail, due to this
> > output:
> > 
> > <-00>0: expected "1970-01-01 00:00:00 - (-00)", got "1970-01-01 
> > 00:00:00 + (-00)"
> > <-00>0: expected "1985-11-05 00:53:21 - (-00)", got "1985-11-05 
> > 00:53:21 + (-00)"
> > <-00>0: expected "2001-09-09 01:46:42 - (-00)", got "2001-09-09 
> > 01:46:42 + (-00)"
> > 
> > Can you please look into that? I cannot judge whether - and +
> > should be treated as equivalent or not.
> 
> "-" signals "I don't know what the time zone is, so I'm using UTC".

Thanks. This is not documented in POSIX [1] nor in the man-pages [2].
Would it make sense that I suggest it to be documented in the man-pages?

Bruno

[1] https://pubs.opengroup.org/onlinepubs/9699919799/functions/strftime_l.html
[2] https://man7.org/linux/man-pages/man3/strftime.3.html






Re: [PATCH 6/7] nstrftime, time_rz: don’t depend on tzname

2024-06-18 Thread Bruno Haible
Paul Eggert wrote:
> > After the Solaris crash fix, the nstrftime tests still fail, due to this
> > output:
> > 
> > <-00>0: expected "1970-01-01 00:00:00 - (-00)", got "1970-01-01 
> > 00:00:00 + (-00)"
> > <-00>0: expected "1985-11-05 00:53:21 - (-00)", got "1985-11-05 
> > 00:53:21 + (-00)"
> > <-00>0: expected "2001-09-09 01:46:42 - (-00)", got "2001-09-09 
> > 01:46:42 + (-00)"
> ...
> I installed the attached to try to fix that issue. Thanks for reporting it.

Thanks. I confirm it fixes the test failure on Solaris 11.4.

But there are two problems:

1) On FreeBSD 5.2.1 and OpenBSD 6.0, I see a compiler warning:

gcc -std=gnu99 -DHAVE_CONFIG_H -I. -I../../gllib -I..  
-DGNULIB_STRICT_CHECKING=1 -I/home/bruno/include -I/usr/local/include -Wall 
-D_THREAD_SAFE  -g -O2 -MT c-nstrftime.o -MD -MP -MF .deps/c-nstrftime.Tpo -c 
-o c-nstrftime.o ../../gllib/c-nstrftime.c
In file included from ../../gllib/c-nstrftime.c:20:
../../gllib/strftime.c: In function `__strftime_internal':
../../gllib/strftime.c:1471: warning: label `underlying_strftime' defined but 
not used

Also, there is an inconsistency: In underlying_strftime, the condition is
  # if USE_C_LOCALE && (HAVE_STRFTIME_L || HAVE_STRFTIME_LZ)
whereas the rest of the code has
  # if USE_C_LOCALE && HAVE_STRFTIME_L
and also a dozen of
  # if USE_C_LOCALE && !HAVE_STRFTIME_L

Fixed through the first patch below.

2) On NetBSD, one out of 4 unit tests fails:

PASS: test-c-nstrftime-1.sh
PASS: test-c-nstrftime-2.sh
PASS: test-nstrftime-1.sh
FAIL: test-nstrftime-2.sh

The cause is a crash:
main
  -> locales_test
   -> FUNC_CHECKED
-> nstrftime
 -> __strftime_internal
  -> underlying_strftime
   -> strftime_lz
-> _fmt
 -> _fmt
  -> __tzgetname50

tzgetname = __tzgetname50 assumes that its first argument is != NULL.

strftime_lz and _fmt pass their timezone_t argument down.

The crashing call is
  underlying_strftime (tz=NULL, ubuf, ubufsize=1024, modifier=0, 
format_char='c', tp)

tz=NULL means universal time (a.k.a. GMT) in our strftime.h, but is undefined
behaviour for NetBSD's functions. See https://man.netbsd.org/tzset.3 .

Fixed through the second patch below.

Bruno

>From 0e5d4c8bc02ea8615e43cae70a9fc114eabcf778 Mon Sep 17 00:00:00 2001
From: Bruno Haible 
Date: Tue, 18 Jun 2024 14:27:18 +0200
Subject: [PATCH 1/3] c-nstrftime: Fix warning on platforms without strftime_l.

* lib/strftime.c: Add comment regarding HAVE_STRFTIME_L.
(underlying_strftime): Don't define if this function is not used.
Correct indentation. Simplify #if condition.
(__strftime_internal): Disable code that is not used on platforms
without strftime_l.
---
 ChangeLog  |  9 +
 lib/strftime.c | 22 +++---
 2 files changed, 24 insertions(+), 7 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 75f06623d6..cb9076 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+2024-06-18  Bruno Haible  
+
+	c-nstrftime: Fix warning on platforms without strftime_l.
+	* lib/strftime.c: Add comment regarding HAVE_STRFTIME_L.
+	(underlying_strftime): Don't define if this function is not used.
+	Correct indentation. Simplify #if condition.
+	(__strftime_internal): Disable code that is not used on platforms
+	without strftime_l.
+
 2024-06-17  Paul Eggert  
 
 	Improve wording for Y2038 and largefile probes
diff --git a/lib/strftime.c b/lib/strftime.c
index ff52fc8119..a757b4f313 100644
--- a/lib/strftime.c
+++ b/lib/strftime.c
@@ -38,8 +38,6 @@
 # include "time-internal.h"
 #endif
 
-#define HAVE_NATIVE_TIME_Z (USE_C_LOCALE ? HAVE_STRFTIME_LZ : HAVE_STRFTIME_Z)
-
 /* Whether to require GNU behavior for AM and PM indicators, even on
other platforms.  This matters only in non-C locales.
The default is to require it; you can override this via
@@ -377,6 +375,15 @@ memcpy_uppcase (CHAR_T *dest, const CHAR_T *src, size_t len LOCALE_PARAM)
 #endif
 
 
+/* Note: We assume that HAVE_STRFTIME_LZ implies HAVE_STRFTIME_L.
+   Otherwise, we would have to write (HAVE_STRFTIME_L || HAVE_STRFTIME_LZ)
+   instead of HAVE_STRFTIME_L everywhere.  */
+
+/* Define to 1 if we can use the system's native functions that takes a
+   timezone_t argument.  As of 2024, this is only true on NetBSD.  */
+#define HAVE_NATIVE_TIME_Z \
+  (USE_C_LOCALE && HAVE_STRFTIME_L ? HAVE_STRFTIME_LZ : HAVE_STRFTIME_Z)
+
 #if USE_C_LOCALE && HAVE_STRFTIME_L
 
 /* Cache for the C locale object.
@@ -837,7 +844,8 @@ static size_t __strftime_internal (STREAM_OR_CHAR_T *, STRFTIME_ARG (size_t)
bool, enum pad_style, int, bool *
extra_args_spec LOCALE_PARAM);
 
-#ifndef _LIBC
+#if !defined _LIBC \
+&& (!(USE_C_LOCALE && !HAVE_STRFTIME_L) || !HAVE_STRUCT_TM_TM_ZONE)
 
 /* Make sure we're calling the actual underlying strftime.
   

Re: [PATCH 6/7] nstrftime, -0000

2024-06-18 Thread Paul Eggert

On 2024-06-18 05:20, Bruno Haible wrote:

Thanks. This is not documented in POSIX [1] nor in the man-pages [2].
Would it make sense that I suggest it to be documented in the man-pages?


That'd be fine, yes. It's a convention in TZDB, e.g.:

  $ TZ=Factory date +'%Y-%m-%d %H:%M:%S %z (%Z)'
  2024-06-18 15:29:50 - (-00)

POSIX allows this, but doesn't require or document it.



Re: [PATCH 6/7] nstrftime, time_rz: don’t depend on tzname

2024-06-18 Thread Paul Eggert

On 2024-06-18 06:02, Bruno Haible wrote:

tz=NULL means universal time (a.k.a. GMT) in our strftime.h, but is undefined
behaviour for NetBSD's functions.


Thanks for the fix. I tweaked it via the attached. The "0" at the end of 
"UTC0" is better if the zoneinfo files are missing.From 562ed134d6cfa9956a72ff0d1c2e7aa84474c7c0 Mon Sep 17 00:00:00 2001
From: Paul Eggert 
Date: Tue, 18 Jun 2024 08:21:44 -0700
Subject: [PATCH] nstrftime: tweak volatile access

* lib/strftime.c (utc_timezone): Avoid unnecessary access to volatile.
---
 ChangeLog  |  5 +
 lib/strftime.c | 14 --
 2 files changed, 13 insertions(+), 6 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 0c39edd886..1d5c743711 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2024-06-18  Paul Eggert  
+
+	nstrftime: tweak volatile access
+	* lib/strftime.c (utc_timezone): Avoid unnecessary access to volatile.
+
 2024-06-18  Bruno Haible  
 
 	nstrftime: Fix crash on NetBSD 10.0.
diff --git a/lib/strftime.c b/lib/strftime.c
index ffc1670f23..e21a356e80 100644
--- a/lib/strftime.c
+++ b/lib/strftime.c
@@ -405,9 +405,10 @@ c_locale (void)
 
 #if HAVE_NATIVE_TIME_Z
 
-/* Cache for the UTC time zone object.
-   Marked volatile so that different threads see the same value
-   (avoids locking).  */
+/* On NetBSD a null tz has undefined behavior, so use a non-null tz.
+   Cache the UTC time zone object in a volatile variable for improved
+   thread safety.  This is good enough in practice, although in theory
+   stdatomic.h should be used.  */
 static volatile timezone_t utc_timezone_cache;
 
 /* Return the UTC time zone object, or (timezone_t) 0 with errno set
@@ -415,9 +416,10 @@ static volatile timezone_t utc_timezone_cache;
 static timezone_t
 utc_timezone (void)
 {
-  if (!utc_timezone_cache)
-utc_timezone_cache = tzalloc ("UTC");
-  return utc_timezone_cache;
+  timezone_t tz = utc_timezone_cache;
+  if (!tz)
+utc_timezone_cache = tz = tzalloc ("UTC0");
+  return tz;
 }
 
 #endif
-- 
2.43.0



u*-vasnprintf: Fix handling of %ls, %lc directives on Solaris, MSVC

2024-06-18 Thread Bruno Haible
In lib/vasnprintf.c the first two invocations of DCHAR_MBSNLEN

 w = DCHAR_MBSNLEN (result + length, count);

look wrong, because the memory beyond result + length has not been
initialized at that point. This code handles the %ls and %lc directives.
The platforms where this code is enabled are Solaris and MSVC. And
indeed, once I add tests for the %ls and %lc directives, I see them
crash. On Solaris 11.4:


FAIL: unistdio/test-u16-vasnprintf2.sh
==

../../gltests/unistdio/test-u16-vasnprintf2.sh: line 20: 3887: Memory 
fault(coredump)
../../build-aux/test-driver: line 116: 3885: Memory fault(coredump)
FAIL unistdio/test-u16-vasnprintf2.sh (exit status: 267)

FAIL: unistdio/test-u16-vasnprintf3.sh
==

../../gltests/unistdio/test-u16-vasnprintf3.sh: line 20: 3895: Memory 
fault(coredump)
../../build-aux/test-driver: line 116: 3893: Memory fault(coredump)
FAIL unistdio/test-u16-vasnprintf3.sh (exit status: 267)

FAIL: unistdio/test-u32-vasnprintf3.sh
==

../../gltests/unistdio/test-u32-vasnprintf3.c:120: assertion 'u32_strcmp 
(result, expected) == 0' failed
../../gltests/unistdio/test-u32-vasnprintf3.sh: line 20: 3915: Abort(coredump)
../../build-aux/test-driver: line 116: 3913: Abort(coredump)
FAIL unistdio/test-u32-vasnprintf3.sh (exit status: 262)

FAIL: unistdio/test-u8-vasnprintf2.sh
=

../../gltests/unistdio/test-u8-vasnprintf2.sh: line 20: 3927: Memory 
fault(coredump)
../../build-aux/test-driver: line 116: 3925: Memory fault(coredump)
FAIL unistdio/test-u8-vasnprintf2.sh (exit status: 267)

FAIL: unistdio/test-u8-vasnprintf3.sh
=

../../gltests/unistdio/test-u8-vasnprintf3.sh: line 20: 3935: Memory 
fault(coredump)
../../build-aux/test-driver: line 116: 3933: Memory fault(coredump)
FAIL unistdio/test-u8-vasnprintf3.sh (exit status: 267)

FAIL: unistdio/test-ulc-vasnprintf3.sh
==

../../gltests/unistdio/test-ulc-vasnprintf3.sh: line 20: 3955: Memory 
fault(coredump)
../../build-aux/test-driver: line 116: 3953: Memory fault(coredump)
FAIL unistdio/test-ulc-vasnprintf3.sh (exit status: 267)


And similarly on MSVC 14.30.

The following patches fix the problem and add the unit tests.


2024-06-18  Bruno Haible  

u*-vasnprintf tests: Add tests of %ls directive.
* tests/unistdio/test-u8-vasnprintf2.c (test_function): Add tests of
the %ls directive with non-ASCII argument.
* tests/unistdio/test-u8-vasnprintf3.c (test_function): Likewise.
* tests/unistdio/test-u16-vasnprintf2.c (test_function): Likewise.
* tests/unistdio/test-u16-vasnprintf3.c (test_function): Likewise.
* tests/unistdio/test-u32-vasnprintf2.c (test_function): Likewise.
* tests/unistdio/test-u32-vasnprintf3.c (test_function): Likewise.
* tests/unistdio/test-ulc-vasnprintf2.c (test_function): Likewise.
* tests/unistdio/test-ulc-vasnprintf3.c (test_function): Likewise.

u*-vasnprintf: Fix handling of %ls, %lc directives on Solaris, MSVC.
* lib/vasnprintf.c (VASNPRINTF): When implementing the %ls, %lc
directives ourselves: Rename variable 'characters' to 'bytes'. Also
count characters, if necessary for the width handling. Fix
DCHAR_MBSNLEN invocation.

2024-06-18  Bruno Haible  

vasnprintf: Refactor.
* lib/vasnprintf.c (VASNPRINTF) [!DCHAR_IS_TCHAR]: Reduce the scope of
the tmpsrc variables.

>From ef47dacd8bc1088110c09aac17ce9099dc7b05b5 Mon Sep 17 00:00:00 2001
From: Bruno Haible 
Date: Tue, 18 Jun 2024 03:16:17 +0200
Subject: [PATCH 1/3] vasnprintf: Refactor.

* lib/vasnprintf.c (VASNPRINTF) [!DCHAR_IS_TCHAR]: Reduce the scope of
the tmpsrc variables.
---
 ChangeLog|   6 +++
 lib/vasnprintf.c | 130 +--
 2 files changed, 74 insertions(+), 62 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 1d5c743711..4b1ee34b9d 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2024-06-18  Bruno Haible  
+
+	vasnprintf: Refactor.
+	* lib/vasnprintf.c (VASNPRINTF) [!DCHAR_IS_TCHAR]: Reduce the scope of
+	the tmpsrc variables.
+
 2024-06-18  Paul Eggert  
 
 	nstrftime: tweak volatile access
diff --git a/lib/vasnprintf.c b/lib/vasnprintf.c
index 0242dd3f55..f9580f7ef4 100644
--- a/lib/vasnprintf.c
+++ b/lib/vasnprintf.c
@@ -3190,7 +3190,6 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
 #  if !DCHAR_IS_TCHAR
   /* This code assumes that TCHAR_T is 'char'.  */
   static_assert (sizeof (TCHAR_T) == 1);
-  TCHAR_T *tmpsrc;
   DCHAR_T *tmpdst;
   size_t tmpdst_len;
 #  endif
@@ -3266,50 +3265,54 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
 #  endif
 
 #  if !DCHAR_IS_TCHAR
-  /* Convert the string into a piece of temporary memory.  */
-  

mbslen: Add tests

2024-06-18 Thread Bruno Haible
The mbslen has 2 different implementations (one relying on mbuiterf, one
relying on mcel). To avoid behavioural differences, a unit test is in order.


2024-06-18  Bruno Haible  

mbslen: Add tests.
* tests/test-mbslen.c: New file.
* tests/test-mbslen.sh: New file, based on tests/test-mbsspn.sh.
* modules/mbslen-tests: New file.

From ba4f392a04ad0633bd6533c2983c6a980fe9f014 Mon Sep 17 00:00:00 2001
From: Bruno Haible 
Date: Wed, 19 Jun 2024 00:45:46 +0200
Subject: [PATCH] mbslen: Add tests.

* tests/test-mbslen.c: New file.
* tests/test-mbslen.sh: New file, based on tests/test-mbsspn.sh.
* modules/mbslen-tests: New file.
---
 ChangeLog|  7 +++
 modules/mbslen-tests | 18 +
 tests/test-mbslen.c  | 47 
 tests/test-mbslen.sh | 15 ++
 4 files changed, 87 insertions(+)
 create mode 100644 modules/mbslen-tests
 create mode 100644 tests/test-mbslen.c
 create mode 100755 tests/test-mbslen.sh

diff --git a/ChangeLog b/ChangeLog
index 43b8424b6b..7e66ba5b11 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2024-06-18  Bruno Haible  
+
+	mbslen: Add tests.
+	* tests/test-mbslen.c: New file.
+	* tests/test-mbslen.sh: New file, based on tests/test-mbsspn.sh.
+	* modules/mbslen-tests: New file.
+
 2024-06-18  Bruno Haible  
 
 	u*-vasnprintf tests: Add tests of %ls directive.
diff --git a/modules/mbslen-tests b/modules/mbslen-tests
new file mode 100644
index 00..0d21eddab8
--- /dev/null
+++ b/modules/mbslen-tests
@@ -0,0 +1,18 @@
+Files:
+tests/test-mbslen.sh
+tests/test-mbslen.c
+tests/macros.h
+m4/locale-fr.m4
+m4/codeset.m4
+
+Depends-on:
+setlocale
+
+configure.ac:
+gt_LOCALE_FR_UTF8
+
+Makefile.am:
+TESTS += test-mbslen.sh
+TESTS_ENVIRONMENT += LOCALE_FR_UTF8='@LOCALE_FR_UTF8@'
+check_PROGRAMS += test-mbslen
+test_mbslen_LDADD = $(LDADD) $(LIBUNISTRING) $(SETLOCALE_LIB) $(MBRTOWC_LIB) $(LIBC32CONV)
diff --git a/tests/test-mbslen.c b/tests/test-mbslen.c
new file mode 100644
index 00..a762c6448a
--- /dev/null
+++ b/tests/test-mbslen.c
@@ -0,0 +1,47 @@
+/* Test of determining the number of multibyte characters in a string.
+   Copyright (C) 2007-2024 Free Software Foundation, Inc.
+
+   This program is free software: you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation, either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see .  */
+
+/* Written by Bruno Haible , 2024.  */
+
+#include 
+
+#include 
+
+#include 
+
+#include "macros.h"
+
+int
+main ()
+{
+  /* configure should already have checked that the locale is supported.  */
+  if (setlocale (LC_ALL, "") == NULL)
+return 1;
+
+  ASSERT (mbslen ("") == 0);
+  ASSERT (mbslen ("Hello") == 5);
+
+  /* The following tests shows how mbslen() is different from strlen().  */
+  ASSERT (mbslen ("\303\244\303\266") == 2); /* "äö" */
+  ASSERT (mbslen ("7\342\202\254") == 2); /* "7€" */
+  ASSERT (mbslen ("\360\237\220\203") == 1); /* "🐃" */
+
+  ASSERT (mbslen ("\303") == 1); /* invalid multibyte sequence */
+  ASSERT (mbslen ("\342\202") == 2); /* 2x invalid multibyte sequence */
+  ASSERT (mbslen ("\360\237\220") == 3); /* 3x invalid multibyte sequence */
+
+  return test_exit_status;
+}
diff --git a/tests/test-mbslen.sh b/tests/test-mbslen.sh
new file mode 100755
index 00..9ba9f0cbac
--- /dev/null
+++ b/tests/test-mbslen.sh
@@ -0,0 +1,15 @@
+#!/bin/sh
+
+# Test whether a specific UTF-8 locale is installed.
+: "${LOCALE_FR_UTF8=fr_FR.UTF-8}"
+if test $LOCALE_FR_UTF8 = none; then
+  if test -f /usr/bin/localedef; then
+echo "Skipping test: no french Unicode locale is installed"
+  else
+echo "Skipping test: no french Unicode locale is supported"
+  fi
+  exit 77
+fi
+
+LC_ALL=$LOCALE_FR_UTF8 \
+${CHECKER} ./test-mbslen${EXEEXT}
-- 
2.34.1



mbsnlen: Fix bug in mcel-based implementation

2024-06-18 Thread Bruno Haible
The new u*-vasnprintf tests that I added today succeed on all
platforms. But on Solaris 11.4, in a testdir that contains also
the 'mcel-prefer' module, they fail:


FAIL: unistdio/test-ulc-vasnprintf3.sh
==

../../gltests/unistdio/test-ulc-vasnprintf3.c:226: assertion 'strcmp (result, " 
  h\303\251t\303\251rog\303\251n\303\251it\303\251 33") == 0' failed
Stack trace:
0x40c59d print_stack_trace
../../gllib/abort-debug.c:40
0x40c59d rpl_abort
../../gllib/abort-debug.c:94
0x40c0f8 test_function
../../gltests/unistdio/test-ulc-vasnprintf3.c:226
0x40c487 test_vasnprintf
../../gltests/unistdio/test-ulc-vasnprintf3.c:266
0x40c4be main
../../gltests/unistdio/test-ulc-vasnprintf3.c:276
../../gltests/unistdio/test-ulc-vasnprintf3.sh: line 20: 6427: Abort(coredump)
../../build-aux/test-driver: line 113: 6425: Abort(coredump)
FAIL unistdio/test-ulc-vasnprintf3.sh (exit status: 262)


The cause, it turns out, is that
  mbsnlen ("h\251", 1)
returns 2. Which is obvious nonsense: mbsnlen (s, count) should always return
a value ≤ count.

So, I wrote unit tests for mbsnlen, and the mcel-based implementation fails
these tests in many places:

../../gltests/test-mbsnlen.c:35: assertion 'mbsnlen ("", 1) == 1' failed
../../gltests/test-mbsnlen.c:36: assertion 'mbsnlen ("\0", 2) == 2' failed
../../gltests/test-mbsnlen.c:38: assertion 'mbsnlen ("H", 0) == 0' failed
../../gltests/test-mbsnlen.c:40: assertion 'mbsnlen ("H", 2) == 2' failed
../../gltests/test-mbsnlen.c:42: assertion 'mbsnlen ("Hello", 0) == 0' failed
../../gltests/test-mbsnlen.c:43: assertion 'mbsnlen ("Hello", 1) == 1' failed
../../gltests/test-mbsnlen.c:44: assertion 'mbsnlen ("Hello", 2) == 2' failed
../../gltests/test-mbsnlen.c:46: assertion 'mbsnlen ("Hello", 6) == 6' failed
../../gltests/test-mbsnlen.c:50: assertion 'mbsnlen ("\303\244\303\266", 0) == 
0' failed
../../gltests/test-mbsnlen.c:51: assertion 'mbsnlen ("\303\244\303\266", 1) == 
1' failed
../../gltests/test-mbsnlen.c:52: assertion 'mbsnlen ("\303\244\303\266", 2) == 
1' failed
../../gltests/test-mbsnlen.c:53: assertion 'mbsnlen ("\303\244\303\266", 3) == 
2' failed
../../gltests/test-mbsnlen.c:55: assertion 'mbsnlen ("\303\244\303\266", 5) == 
3' failed
../../gltests/test-mbsnlen.c:57: assertion 'mbsnlen ("7\342\202\254", 0) == 0' 
failed
../../gltests/test-mbsnlen.c:58: assertion 'mbsnlen ("7\342\202\254", 1) == 1' 
failed
../../gltests/test-mbsnlen.c:59: assertion 'mbsnlen ("7\342\202\254", 2) == 2' 
failed
../../gltests/test-mbsnlen.c:60: assertion 'mbsnlen ("7\342\202\254", 3) == 2' 
failed
../../gltests/test-mbsnlen.c:62: assertion 'mbsnlen ("7\342\202\254", 5) == 3' 
failed
../../gltests/test-mbsnlen.c:64: assertion 'mbsnlen ("\360\237\220\203", 0) == 
0' failed
../../gltests/test-mbsnlen.c:65: assertion 'mbsnlen ("\360\237\220\203", 1) == 
1' failed
../../gltests/test-mbsnlen.c:66: assertion 'mbsnlen ("\360\237\220\203", 2) == 
1' failed
../../gltests/test-mbsnlen.c:67: assertion 'mbsnlen ("\360\237\220\203", 3) == 
1' failed
../../gltests/test-mbsnlen.c:69: assertion 'mbsnlen ("\360\237\220\203", 5) == 
2' failed
../../gltests/test-mbsnlen.c:73: assertion 'mbsnlen ("\342\202", 2) == 1' failed
../../gltests/test-mbsnlen.c:74: assertion 'mbsnlen ("\360\237\220", 3) == 1' 
failed

The two attached patches make the tests pass. At this point, I don't have
time to deal with the MEE vs. SEE behaviour differences; that has to wait
for later.


2024-06-18  Bruno Haible  

mbsnlen: Add tests.
* tests/test-mbsnlen.c: New file.
* tests/test-mbsnlen.sh: New file, based on tests/test-mbsspn.sh.
* modules/mbsnlen-tests: New file.

mbsnlen: Fix bug (regression 2023-09-26).
* lib/mbsnlen.c (mbsnlen): Fix bug in GNULIB_MCEL_PREFER implementation.

>From b3d39349c9ac177b4640cd0e7d8a9a1e21be58e9 Mon Sep 17 00:00:00 2001
From: Bruno Haible 
Date: Wed, 19 Jun 2024 02:31:30 +0200
Subject: [PATCH 1/2] mbsnlen: Fix bug (regression 2023-09-26).

* lib/mbsnlen.c (mbsnlen): Fix bug in GNULIB_MCEL_PREFER implementation.
---
 ChangeLog | 5 +
 lib/mbsnlen.c | 2 +-
 2 files changed, 6 insertions(+), 1 deletion(-)

diff --git a/ChangeLog b/ChangeLog
index 7e66ba5b11..fbde74072f 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2024-06-18  Bruno Haible  
+
+	mbsnlen: Fix bug (regression 2023-09-26).
+	* lib/mbsnlen.c (mbsnlen): Fix bug in GNULIB_MCEL_PREFER implementation.
+
 2024-06-18  Bruno Haible  
 
 	mbslen: Add tests.
diff --git a/lib/mbsnlen.c b/lib/mbsnlen.c
index baadf163ca..1ce79bfb4b 100644
--- a/lib/mbsnlen.c
+++ b/lib/mbsnlen.c
@@ -40,7 +40,7 @@ mbsnlen (const char *string, size_t len)
   const char *string_end = string + len;
 
 #if GNULIB_MCEL_PREFER
-  for (; *string; string += mcel_scan (string, string_end).len)
+  for (; string < string_end; string += mcel_scan (string, string_end).len)
 count++;
 #else
   mbif_state_t state;
-- 
2.34.1

Fro

copysignl tests: Avoid failure on Solaris 11.4

2024-06-18 Thread Bruno Haible
Building a testdir for module 'copysignl' on Solaris 11.4, with gcc
in 64-bit mode without optimizations, I see a test failure:


FAIL: test-copysignl


../../gltests/test-copysignl.c:90: assertion 'memcmp (&z, &zero, sizeof z) == 
0' failed
Stack trace:
0x408050 print_stack_trace
../../gllib/abort-debug.c:40
0x408050 rpl_abort
../../gllib/abort-debug.c:94
0x407cb9 main
../../gltests/test-copysignl.c:90
../../build-aux/test-driver: line 114: 29294: Abort(coredump)
FAIL test-copysignl (exit status: 262)


The cause is that 'long double' has onlu 80 bits, but sizeof (long double)
is 16, not 10.

This patch fixes the test failure.

This test code exists since 2011, and x86_64 platforms are not rare.
It's astonishing that this test failure has not been seen earlier.


2024-06-18  Bruno Haible  

copysignl tests: Avoid failure on Solaris 11.4.
* tests/test-copysignl.c: Include .
(LDBL_BYTES): New macro.
(main): Use it instead of sizeof (long double).
* modules/copysignl-tests (Depends-on): Add float.

diff --git a/modules/copysignl-tests b/modules/copysignl-tests
index 1cb5f829aa..e3a5b79c96 100644
--- a/modules/copysignl-tests
+++ b/modules/copysignl-tests
@@ -5,6 +5,7 @@ tests/minus-zero.h
 tests/macros.h
 
 Depends-on:
+float
 
 configure.ac:
 
diff --git a/tests/test-copysignl.c b/tests/test-copysignl.c
index 8f5f188872..f17d045b40 100644
--- a/tests/test-copysignl.c
+++ b/tests/test-copysignl.c
@@ -26,6 +26,7 @@ SIGNATURE_CHECK (copysignl, long double, (long double, long 
double));
 #include "macros.h"
 #include "minus-zero.h"
 
+#include 
 #include 
 
 volatile long double x;
@@ -33,6 +34,14 @@ volatile long double y;
 long double z;
 long double zero = 0.0L;
 
+/* Number of bytes occupied by a 'long double' in memory.  */
+#if (defined __ia64 || (defined __x86_64__ || defined __amd64__) || (defined 
__i386 || defined __i386__ || defined _I386 || defined _M_IX86 || defined 
_X86_)) && LDBL_MANT_DIG == 64
+/* 'long double' is little-endian 80-bits "extended precision".  */
+# define LDBL_BYTES 10
+#else
+# define LDBL_BYTES sizeof (long double)
+#endif
+
 int
 main ()
 {
@@ -87,25 +96,25 @@ main ()
   y = 1.0L;
   z = copysignl (x, y);
   ASSERT (z == 0.0L);
-  ASSERT (memcmp (&z, &zero, sizeof z) == 0);
+  ASSERT (memcmp (&z, &zero, LDBL_BYTES) == 0);
 
   x = 0.0L;
   y = -1.0L;
   z = copysignl (x, y);
   ASSERT (z == 0.0L);
-  ASSERT (memcmp (&z, &zero, sizeof z) != 0);
+  ASSERT (memcmp (&z, &zero, LDBL_BYTES) != 0);
 
   x = minus_zerol;
   y = 1.0L;
   z = copysignl (x, y);
   ASSERT (z == 0.0L);
-  ASSERT (memcmp (&z, &zero, sizeof z) == 0);
+  ASSERT (memcmp (&z, &zero, LDBL_BYTES) == 0);
 
   x = minus_zerol;
   y = -1.0L;
   z = copysignl (x, y);
   ASSERT (z == 0.0L);
-  ASSERT (memcmp (&z, &zero, sizeof z) != 0);
+  ASSERT (memcmp (&z, &zero, LDBL_BYTES) != 0);
 
   return test_exit_status;
 }






filemode: Add tests.

2024-06-18 Thread Collin Funk
I ran into a compilation error a long time ago (not Gnulib related)
because I declared strmode using the mode_t argument unconditionally.
This is an issue because FreeBSD uses int as the first argument and
not mode_t, which is typedef'd to __uint16_t. This test is mostly to
make sure that doesn't happen due to this module. I've added some
basic functionality tests too.

NetBSD fixed that declaration in 1997 [1], FreeBSD did in version
14.0 [2]. OpenBSD still has it declared with an int argument even
though mode_t is a __uint32_t there [3] [4] [5].

Collin

[1] 
https://github.com/NetBSD/src/commit/3664382e532de079a7dc0f9430d55ce2419af50d
[2] 
https://github.com/freebsd/freebsd-src/commit/849dcdb1c0c50b13f97d67c912f0edac82688281
[3] 
https://github.com/openbsd/src/blob/1245b84dd8b155eea7f3aeffc9acb78e7116673b/include/string.h#L131
[4] 
https://github.com/openbsd/src/blob/1245b84dd8b155eea7f3aeffc9acb78e7116673b/sys/sys/_types.h#L54
[5] https://man.openbsd.org/strmode.3From d8e12a7f5082deaa2e26ca2d908915f3197ba6b1 Mon Sep 17 00:00:00 2001
From: Collin Funk 
Date: Tue, 18 Jun 2024 21:21:47 -0700
Subject: [PATCH] filemode: Add tests.

* modules/filemode-tests: New file.
* tests/test-filemode.c: New file.
---
 ChangeLog  |  6 
 modules/filemode-tests | 11 ++
 tests/test-filemode.c  | 78 ++
 3 files changed, 95 insertions(+)
 create mode 100644 modules/filemode-tests
 create mode 100644 tests/test-filemode.c

diff --git a/ChangeLog b/ChangeLog
index 988f36b6fc..d7abbaadce 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2024-06-18  Collin Funk  
+
+	filemode: Add tests.
+	* modules/filemode-tests: New file.
+	* tests/test-filemode.c: New file.
+
 2024-06-18  Bruno Haible  
 
 	copysignl tests: Avoid failure on Solaris 11.4.
diff --git a/modules/filemode-tests b/modules/filemode-tests
new file mode 100644
index 00..983bc1e672
--- /dev/null
+++ b/modules/filemode-tests
@@ -0,0 +1,11 @@
+Files:
+tests/test-filemode.c
+tests/macros.h
+
+Depends-on:
+
+configure.ac:
+
+Makefile.am:
+TESTS += test-filemode
+check_PROGRAMS += test-filemode
diff --git a/tests/test-filemode.c b/tests/test-filemode.c
new file mode 100644
index 00..56c2fdc033
--- /dev/null
+++ b/tests/test-filemode.c
@@ -0,0 +1,78 @@
+/* Test the sig2str and str2sig functions.
+   Copyright (C) 2024 Free Software Foundation, Inc.
+
+   This file is free software: you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published
+   by the Free Software Foundation, either version 3 of the License,
+   or (at your option) any later version.
+
+   This file is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see .  */
+
+/* Written by Collin Funk , 2024.  */
+
+#include 
+
+/* Specification.  */
+#include "filemode.h"
+
+#include 
+
+/* The strmode function is already defined on some systems in  or
+   .  On FreeBSD versions 13 and lower the function takes an int
+   instead of a mode_t (uint16_t) as it's first argument.  Include these
+   headers here to make sure our declaration doesn't conflict with system
+   functions.  */
+#include 
+#include 
+
+#include "macros.h"
+
+struct mode_to_string
+{
+  mode_t mode;
+  char str[12];
+};
+
+static const struct mode_to_string table[] =
+  {
+{ S_IFCHR, "c- " },
+{ S_IFDIR, "d- " },
+{ S_IFIFO, "p- " },
+{ S_IFREG, "-- " },
+{ S_IFCHR | S_IRUSR | S_IWGRP | S_IXOTH, "cr---w---x " },
+{ S_IFDIR | S_IXUSR | S_IRGRP | S_IWOTH, "d--xr---w- " },
+{ S_IFIFO | S_IWUSR | S_IXGRP | S_IROTH, "p-w---xr-- " },
+#if S_ISUID
+{ S_IFREG | S_ISUID, "---S-- " },
+{ S_IFREG | S_ISUID | S_IXUSR, "---s-- " },
+#endif
+#if S_ISGID
+{ S_IFREG | S_ISGID, "--S--- " },
+{ S_IFREG | S_ISGID | S_IXGRP, "--s--- " },
+#endif
+#if S_ISVTX
+{ S_IFREG | S_ISVTX, "-T " },
+{ S_IFREG | S_ISVTX | S_IXOTH, "-t " },
+#endif
+  };
+
+int
+main (void)
+{
+  size_t i;
+  char buffer[12];
+
+  for (i = 0; i < SIZEOF (table); ++i)
+{
+  strmode (table[i].mode, buffer);
+  ASSERT (STREQ (table[i].str, buffer));
+}
+
+  return test_exit_status;
+}
-- 
2.45.2