On 2026-05-06 12:09, Paul Eggert wrote:
It appears that test-regex.c is written
wrongly; its use of re.fastmap is undocumented. Possibly this means my
regex fix just lucked out and is not really a fix. I'll look into it.
After looking into it, it seems that this was entirely the fault of the
test program. I installed the attached patches into Gnulib to fix the
test issues I found.
I found some other annoyances with GCC 16's warnings spitting out both
false positives and good advice, notably that unless you need a constant
expression the compound literal ((type) {expr}) is often better than the
cast ((type) (expr)), as the cast has too much power.
I fixed all the GCC 16 warning issues I found in the Gnulib files copied
to coreutils/lib, and will send out emails to bug-gnulib shortly. Still
haven't gotten around to looking at the files copied to
coreutils/gnulib-tests, which are lower priority.From ba1c85827473ebb75458f870965cf499700065b6 Mon Sep 17 00:00:00 2001
From: Paul Eggert <[email protected]>
Date: Thu, 7 May 2026 11:23:18 -0700
Subject: [PATCH 1/3] regex-tests: fix usage of fastmap API
* tests/test-regex.c (main): Use documented fastmap API
rather than relying on undocumented behavior.
---
ChangeLog | 6 ++++++
tests/test-regex.c | 38 +++++++++++++++++++++++++-------------
2 files changed, 31 insertions(+), 13 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index 27df61801a..c2c49d0ca5 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2026-05-07 Paul Eggert <[email protected]>
+
+ regex-tests: fix usage of fastmap API
+ * tests/test-regex.c (main): Use documented fastmap API
+ rather than relying on undocumented behavior.
+
2026-05-06 Paul Eggert <[email protected]>
manywarnings: no ‘s’ at end of ‘-Wuseless-cast’
diff --git a/tests/test-regex.c b/tests/test-regex.c
index 7b61895744..f059ad2f63 100644
--- a/tests/test-regex.c
+++ b/tests/test-regex.c
@@ -267,22 +267,34 @@ main (void)
for (int j = 0; j < 3; j++)
{
static char const str[3][2] = { "\xd3", "\xf2", "\xf3" };
- regex_t re;
- int err = regcomp (&re, str[i], REG_ICASE | REG_NOSUB);
- if (err)
+ re_set_syntax (RE_ICASE);
+ memset (®ex, 0, sizeof regex);
+ s = re_compile_pattern (str[i], 1, ®ex);
+ if (s)
{
- char buf[500];
- regerror (err, &re, buf, sizeof buf);
- report_error ("regcomp \\x%02x failed: %s",
- (unsigned char) str[i][0], buf);
+ report_error ("re_compile_pattern \\x%02x failed: %s",
+ (unsigned char) str[i][0], s);
continue;
}
+ int without = re_search (®ex, str[j], 1, 0, 1, NULL);
+ regfree (®ex);
+
+ memset (®ex, 0, sizeof regex);
+ regex.fastmap = malloc (UCHAR_MAX + 1);
+ if (!regex.fastmap)
+ {
+ report_error ("malloc failed");
+ continue;
+ }
+ s = re_compile_pattern (str[i], 1, ®ex);
+ if (s)
+ {
+ report_error ("re_compile_pattern \\x%02x failed(!): %s",
+ (unsigned char) str[i][0], s);
+ continue;
+ }
+ int with = re_search (®ex, str[j], 1, 0, 1, NULL);
- int with = regexec (&re, str[j], 0, NULL, 0);
- free (re.fastmap);
- re.fastmap = NULL;
- re.fastmap_accurate = 0;
- int without = regexec (&re, str[j], 0, NULL, 0);
if (with != without)
report_error
("fastmap mismatch: pattern = \\x%02x, string = \\x%02x,"
@@ -290,7 +302,7 @@ main (void)
(unsigned char) str[i][0], (unsigned char) str[j][0],
with, without);
- regfree (&re);
+ regfree (®ex);
}
if (! setlocale (LC_ALL, "C"))
--
2.54.0
From d60036ddca99d4f682f6412a129d8aa8b51e1cc2 Mon Sep 17 00:00:00 2001
From: Paul Eggert <[email protected]>
Date: Thu, 7 May 2026 11:24:22 -0700
Subject: [PATCH 2/3] bench-tests: work with wchar-single
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
* modules/mbiter-bench-tests, modules/mbiterf-bench-tests:
* modules/mbswidth-bench-tests, modules/mbuiter-bench-tests:
* modules/mbuiterf-bench-tests, modules/mcel-bench-tests:
(Depends-on): Add streq.
* tests/bench-mbiter.c, tests/bench-mbiterf.c, tests/bench-mbswidth.c:
* tests/bench-mbuiter.c, tests/bench-mbuiterf.c, tests/bench-mcel.c:
If GNULIB_WCHAR_SINGLE_LOCALE, don’t call setlocale with different
locales.
---
ChangeLog | 10 ++++++++++
modules/mbiter-bench-tests | 1 +
modules/mbiterf-bench-tests | 1 +
modules/mbswidth-bench-tests | 1 +
modules/mbuiter-bench-tests | 1 +
modules/mbuiterf-bench-tests | 1 +
modules/mcel-bench-tests | 1 +
tests/bench-mbiter.c | 20 +++++++++++++++-----
tests/bench-mbiterf.c | 20 +++++++++++++++-----
tests/bench-mbswidth.c | 20 +++++++++++++++-----
tests/bench-mbuiter.c | 20 +++++++++++++++-----
tests/bench-mbuiterf.c | 20 +++++++++++++++-----
tests/bench-mcel.c | 21 ++++++++++++++-------
13 files changed, 105 insertions(+), 32 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index c2c49d0ca5..a3e37f6e93 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,15 @@
2026-05-07 Paul Eggert <[email protected]>
+ bench-tests: work with wchar-single
+ * modules/mbiter-bench-tests, modules/mbiterf-bench-tests:
+ * modules/mbswidth-bench-tests, modules/mbuiter-bench-tests:
+ * modules/mbuiterf-bench-tests, modules/mcel-bench-tests:
+ (Depends-on): Add streq.
+ * tests/bench-mbiter.c, tests/bench-mbiterf.c, tests/bench-mbswidth.c:
+ * tests/bench-mbuiter.c, tests/bench-mbuiterf.c, tests/bench-mcel.c:
+ If GNULIB_WCHAR_SINGLE_LOCALE, don’t call setlocale with different
+ locales.
+
regex-tests: fix usage of fastmap API
* tests/test-regex.c (main): Use documented fastmap API
rather than relying on undocumented behavior.
diff --git a/modules/mbiter-bench-tests b/modules/mbiter-bench-tests
index ec22673d1a..1648054e84 100644
--- a/modules/mbiter-bench-tests
+++ b/modules/mbiter-bench-tests
@@ -7,6 +7,7 @@ Depends-on:
mbrtoc32-regular
mbiter
setlocale
+streq
striconv
getrusage
gettimeofday
diff --git a/modules/mbiterf-bench-tests b/modules/mbiterf-bench-tests
index b4b530dc5a..dc837a2304 100644
--- a/modules/mbiterf-bench-tests
+++ b/modules/mbiterf-bench-tests
@@ -7,6 +7,7 @@ Depends-on:
mbrtoc32-regular
mbiterf
setlocale
+streq
striconv
getrusage
gettimeofday
diff --git a/modules/mbswidth-bench-tests b/modules/mbswidth-bench-tests
index f8edf91dfe..8ffc21db2e 100644
--- a/modules/mbswidth-bench-tests
+++ b/modules/mbswidth-bench-tests
@@ -7,6 +7,7 @@ Depends-on:
mbrtoc32-regular
mbswidth
setlocale
+streq
striconv
getrusage
gettimeofday
diff --git a/modules/mbuiter-bench-tests b/modules/mbuiter-bench-tests
index de98778fd6..29b72b342e 100644
--- a/modules/mbuiter-bench-tests
+++ b/modules/mbuiter-bench-tests
@@ -7,6 +7,7 @@ Depends-on:
mbrtoc32-regular
mbuiter
setlocale
+streq
striconv
getrusage
gettimeofday
diff --git a/modules/mbuiterf-bench-tests b/modules/mbuiterf-bench-tests
index cf806ecc49..c9551bff88 100644
--- a/modules/mbuiterf-bench-tests
+++ b/modules/mbuiterf-bench-tests
@@ -7,6 +7,7 @@ Depends-on:
mbrtoc32-regular
mbuiterf
setlocale
+streq
striconv
getrusage
gettimeofday
diff --git a/modules/mcel-bench-tests b/modules/mcel-bench-tests
index 0c54aad819..1599505fdd 100644
--- a/modules/mcel-bench-tests
+++ b/modules/mcel-bench-tests
@@ -11,6 +11,7 @@ mbuiter
mbuiterf
mcel
setlocale
+streq
striconv
getrusage
gettimeofday
diff --git a/tests/bench-mbiter.c b/tests/bench-mbiter.c
index b7bea54805..3593c164e6 100644
--- a/tests/bench-mbiter.c
+++ b/tests/bench-mbiter.c
@@ -27,12 +27,26 @@
unsigned long long volatile result;
+#ifndef GNULIB_WCHAR_SINGLE_LOCALE
+# define GNULIB_WCHAR_SINGLE_LOCALE 0
+#endif
+
static void
do_test (char test, int repeat, const char *locale_name, const char *text)
{
printf ("Test %c\n", test);
- if (setlocale (LC_ALL, locale_name) != NULL)
+
+ static char const *current_locale_name;
+ if (GNULIB_WCHAR_SINGLE_LOCALE && current_locale_name
+ && !streq (locale_name, current_locale_name))
+ printf ("Skipping test: earlier locale %s != test locale %s\n",
+ current_locale_name, locale_name);
+ else if (!setlocale (LC_ALL, locale_name))
+ printf ("Skipping test: locale %s not installed.\n", locale_name);
+ else
{
+ current_locale_name = locale_name;
+
struct timings_state ts;
timing_start (&ts);
@@ -51,10 +65,6 @@ do_test (char test, int repeat, const char *locale_name, const char *text)
timing_end (&ts);
timing_output (&ts);
}
- else
- {
- printf ("Skipping test: locale %s not installed.\n", locale_name);
- }
printf ("\n");
}
diff --git a/tests/bench-mbiterf.c b/tests/bench-mbiterf.c
index 505e5fbc6a..57564f5265 100644
--- a/tests/bench-mbiterf.c
+++ b/tests/bench-mbiterf.c
@@ -27,12 +27,26 @@
unsigned long long volatile result;
+#ifndef GNULIB_WCHAR_SINGLE_LOCALE
+# define GNULIB_WCHAR_SINGLE_LOCALE 0
+#endif
+
static void
do_test (char test, int repeat, const char *locale_name, const char *text)
{
printf ("Test %c\n", test);
- if (setlocale (LC_ALL, locale_name) != NULL)
+
+ static char const *current_locale_name;
+ if (GNULIB_WCHAR_SINGLE_LOCALE && current_locale_name
+ && !streq (locale_name, current_locale_name))
+ printf ("Skipping test: earlier locale %s != test locale %s\n",
+ current_locale_name, locale_name);
+ else if (!setlocale (LC_ALL, locale_name))
+ printf ("Skipping test: locale %s not installed.\n", locale_name);
+ else
{
+ current_locale_name = locale_name;
+
struct timings_state ts;
timing_start (&ts);
@@ -55,10 +69,6 @@ do_test (char test, int repeat, const char *locale_name, const char *text)
timing_end (&ts);
timing_output (&ts);
}
- else
- {
- printf ("Skipping test: locale %s not installed.\n", locale_name);
- }
printf ("\n");
}
diff --git a/tests/bench-mbswidth.c b/tests/bench-mbswidth.c
index 4facad04fc..bad0adcf5c 100644
--- a/tests/bench-mbswidth.c
+++ b/tests/bench-mbswidth.c
@@ -25,12 +25,26 @@
#include "bench-multibyte.h"
#include "mbswidth.h"
+#ifndef GNULIB_WCHAR_SINGLE_LOCALE
+# define GNULIB_WCHAR_SINGLE_LOCALE 0
+#endif
+
static void
do_test (char test, int repeat, const char *locale_name, const char *text)
{
printf ("Test %c\n", test);
- if (setlocale (LC_ALL, locale_name) != NULL)
+
+ static char const *current_locale_name;
+ if (GNULIB_WCHAR_SINGLE_LOCALE && current_locale_name
+ && !streq (locale_name, current_locale_name))
+ printf ("Skipping test: earlier locale %s != test locale %s\n",
+ current_locale_name, locale_name);
+ else if (!setlocale (LC_ALL, locale_name))
+ printf ("Skipping test: locale %s not installed.\n", locale_name);
+ else
{
+ current_locale_name = locale_name;
+
struct timings_state ts;
timing_start (&ts);
@@ -42,10 +56,6 @@ do_test (char test, int repeat, const char *locale_name, const char *text)
timing_end (&ts);
timing_output (&ts);
}
- else
- {
- printf ("Skipping test: locale %s not installed.\n", locale_name);
- }
printf ("\n");
}
diff --git a/tests/bench-mbuiter.c b/tests/bench-mbuiter.c
index 2fda0506c9..b1e4eccc6f 100644
--- a/tests/bench-mbuiter.c
+++ b/tests/bench-mbuiter.c
@@ -27,12 +27,26 @@
unsigned long long volatile result;
+#ifndef GNULIB_WCHAR_SINGLE_LOCALE
+# define GNULIB_WCHAR_SINGLE_LOCALE 0
+#endif
+
static void
do_test (char test, int repeat, const char *locale_name, const char *text)
{
printf ("Test %c\n", test);
- if (setlocale (LC_ALL, locale_name) != NULL)
+
+ static char const *current_locale_name;
+ if (GNULIB_WCHAR_SINGLE_LOCALE && current_locale_name
+ && !streq (locale_name, current_locale_name))
+ printf ("Skipping test: earlier locale %s != test locale %s\n",
+ current_locale_name, locale_name);
+ else if (!setlocale (LC_ALL, locale_name))
+ printf ("Skipping test: locale %s not installed.\n", locale_name);
+ else
{
+ current_locale_name = locale_name;
+
struct timings_state ts;
timing_start (&ts);
@@ -50,10 +64,6 @@ do_test (char test, int repeat, const char *locale_name, const char *text)
timing_end (&ts);
timing_output (&ts);
}
- else
- {
- printf ("Skipping test: locale %s not installed.\n", locale_name);
- }
printf ("\n");
}
diff --git a/tests/bench-mbuiterf.c b/tests/bench-mbuiterf.c
index 5f51c9b01a..92c3174599 100644
--- a/tests/bench-mbuiterf.c
+++ b/tests/bench-mbuiterf.c
@@ -27,12 +27,26 @@
unsigned long long volatile result;
+#ifndef GNULIB_WCHAR_SINGLE_LOCALE
+# define GNULIB_WCHAR_SINGLE_LOCALE 0
+#endif
+
static void
do_test (char test, int repeat, const char *locale_name, const char *text)
{
printf ("Test %c\n", test);
- if (setlocale (LC_ALL, locale_name) != NULL)
+
+ static char const *current_locale_name;
+ if (GNULIB_WCHAR_SINGLE_LOCALE && current_locale_name
+ && !streq (locale_name, current_locale_name))
+ printf ("Skipping test: earlier locale %s != test locale %s\n",
+ current_locale_name, locale_name);
+ else if (!setlocale (LC_ALL, locale_name))
+ printf ("Skipping test: locale %s not installed.\n", locale_name);
+ else
{
+ current_locale_name = locale_name;
+
struct timings_state ts;
timing_start (&ts);
@@ -53,10 +67,6 @@ do_test (char test, int repeat, const char *locale_name, const char *text)
timing_end (&ts);
timing_output (&ts);
}
- else
- {
- printf ("Skipping test: locale %s not installed.\n", locale_name);
- }
printf ("\n");
}
diff --git a/tests/bench-mcel.c b/tests/bench-mcel.c
index d8f91a4b16..f100a366c1 100644
--- a/tests/bench-mcel.c
+++ b/tests/bench-mcel.c
@@ -191,12 +191,25 @@ do_1_test (test_function test, char const *text,
return sum;
}
+#ifndef GNULIB_WCHAR_SINGLE_LOCALE
+# define GNULIB_WCHAR_SINGLE_LOCALE 0
+#endif
+
static void
do_test (char test, int repeat, char const *locale_name,
char const *text, size_t text_len)
{
- if (setlocale (LC_ALL, locale_name) != NULL)
+ static char const *current_locale_name;
+ if (GNULIB_WCHAR_SINGLE_LOCALE && current_locale_name
+ && !streq (locale_name, current_locale_name))
+ printf ("Skipping test: earlier locale %s != test locale %s\n",
+ current_locale_name, locale_name);
+ else if (!setlocale (LC_ALL, locale_name))
+ printf ("Skipping test: locale %s not installed.\n", locale_name);
+ else
{
+ current_locale_name = locale_name;
+
char const *text_end = text + text_len;
static struct
@@ -220,8 +233,6 @@ do_test (char test, int repeat, char const *locale_name,
testdesc[i].sum =
do_1_test (testdesc[i].fn, text, text_end, repeat, &testdesc[i].ts);
- setlocale (LC_ALL, "C");
-
static bool header_printed;
if (!header_printed)
{
@@ -241,10 +252,6 @@ do_test (char test, int repeat, char const *locale_name,
}
printf ("\n");
}
- else
- {
- printf ("Skipping test: locale %s not installed.\n", locale_name);
- }
}
/* Performs some or all of the following tests:
--
2.54.0
From f762dbf461c65c2740f5a39463c6fc6a06af61b1 Mon Sep 17 00:00:00 2001
From: Paul Eggert <[email protected]>
Date: Thu, 7 May 2026 11:25:37 -0700
Subject: [PATCH 3/3] regex-tests: work with wchar-single
* tests/test-regex-el.c, tests/test-regex-en.c, tests/test-regex-tr.c:
New files, containing the locale-specific parts of the old
tests/test-regex.c.
* modules/regex-tests (Files): Add them. Add m4/locale-en.m4.
(configure.ac): Add gt_LOCALE_EN_UTF8.
(TESTS, check_PROGRAMS):
Add test-regex-el, test-regex-en, test-regex-tr.
(TESTS_ENVIRONMENT, test_regex_el_LDADD, test_regex_en_LDADD)
(test_regex_tr_LDADD): New macros.
* tests/test-regex.c: Do not include <locale.h>, <wctype.h>,
"localcharset.h".
(really_utf8): Remove.
(main): Remove the parts assuming specific locales;
they are now moved to the abovementioned new files.
---
ChangeLog | 16 +++
modules/regex-tests | 13 ++-
tests/test-regex-el.c | 118 ++++++++++++++++++++
tests/test-regex-en.c | 251 ++++++++++++++++++++++++++++++++++++++++++
tests/test-regex-tr.c | 107 ++++++++++++++++++
tests/test-regex.c | 182 ------------------------------
6 files changed, 503 insertions(+), 184 deletions(-)
create mode 100644 tests/test-regex-el.c
create mode 100644 tests/test-regex-en.c
create mode 100644 tests/test-regex-tr.c
diff --git a/ChangeLog b/ChangeLog
index a3e37f6e93..339b89a129 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,21 @@
2026-05-07 Paul Eggert <[email protected]>
+ regex-tests: work with wchar-single
+ * tests/test-regex-el.c, tests/test-regex-en.c, tests/test-regex-tr.c:
+ New files, containing the locale-specific parts of the old
+ tests/test-regex.c.
+ * modules/regex-tests (Files): Add them. Add m4/locale-en.m4.
+ (configure.ac): Add gt_LOCALE_EN_UTF8.
+ (TESTS, check_PROGRAMS):
+ Add test-regex-el, test-regex-en, test-regex-tr.
+ (TESTS_ENVIRONMENT, test_regex_el_LDADD, test_regex_en_LDADD)
+ (test_regex_tr_LDADD): New macros.
+ * tests/test-regex.c: Do not include <locale.h>, <wctype.h>,
+ "localcharset.h".
+ (really_utf8): Remove.
+ (main): Remove the parts assuming specific locales;
+ they are now moved to the abovementioned new files.
+
bench-tests: work with wchar-single
* modules/mbiter-bench-tests, modules/mbiterf-bench-tests:
* modules/mbswidth-bench-tests, modules/mbuiter-bench-tests:
diff --git a/modules/regex-tests b/modules/regex-tests
index 1eea754c5c..9da7634dea 100644
--- a/modules/regex-tests
+++ b/modules/regex-tests
@@ -1,6 +1,10 @@
Files:
tests/test-regex.c
+tests/test-regex-el.c
+tests/test-regex-en.c
+tests/test-regex-tr.c
tests/macros.h
+m4/locale-en.m4
Depends-on:
gettext-h
@@ -10,8 +14,13 @@ streq
configure.ac:
AC_CHECK_DECLS_ONCE([alarm])
+gt_LOCALE_EN_UTF8
Makefile.am:
-TESTS += test-regex
-check_PROGRAMS += test-regex
+TESTS += test-regex test-regex-el test-regex-en test-regex-tr
+TESTS_ENVIRONMENT += LOCALE_EN_UTF8='@LOCALE_EN_UTF8@'
+check_PROGRAMS += test-regex test-regex-el test-regex-en test-regex-tr
test_regex_LDADD = $(LDADD) $(LIBUNISTRING) $(SETLOCALE_LIB) $(MBRTOWC_LIB) @LIBINTL@ $(LIBC32CONV) $(LIBTHREAD)
+test_regex_el_LDADD = $(test_regex_LDADD)
+test_regex_en_LDADD = $(test_regex_LDADD)
+test_regex_tr_LDADD = $(test_regex_LDADD)
diff --git a/tests/test-regex-el.c b/tests/test-regex-el.c
new file mode 100644
index 0000000000..7cdf579d70
--- /dev/null
+++ b/tests/test-regex-el.c
@@ -0,0 +1,118 @@
+/* Test regular expressions
+ Copyright 1996-2001, 2003-2026 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 <https://www.gnu.org/licenses/>. */
+
+#include <config.h>
+
+#include "regex.h"
+
+#include <ctype.h>
+#include <locale.h>
+#include <limits.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#if HAVE_DECL_ALARM
+# include <unistd.h>
+# include <signal.h>
+#endif
+
+static int exit_status;
+
+static void
+report_error (char const *format, ...)
+{
+ va_list args;
+ va_start (args, format);
+ fprintf (stderr, "test-regex: ");
+ vfprintf (stderr, format, args);
+ fprintf (stderr, "\n");
+ va_end (args);
+ exit_status = 1;
+}
+
+int
+main ()
+{
+ struct re_pattern_buffer regex;
+ const char *s;
+
+#if HAVE_DECL_ALARM
+ /* In case a bug causes glibc to go into an infinite loop.
+ The tests should take less than 10 s on a reasonably modern CPU. */
+ int alarm_value = 1000;
+ signal (SIGALRM, SIG_DFL);
+ alarm (alarm_value);
+#endif
+
+ /* Test for glibc bug 20381
+ <https://sourceware.org/bugzilla/show_bug.cgi?id=20381>.
+ Check this only in Greek locales that seem to be working.
+ In macOS 26, for example, setlocale (LC_ALL, "el_GR.ISO8859-7")
+ succeed but acts like the C locale. */
+ if (! ((setlocale (LC_ALL, "el_GR.iso88597")
+ || setlocale (LC_ALL, "el_GR.ISO8859-7")
+ || setlocale (LC_ALL, "el_GR.iso8859-7"))
+ && toupper (0xf2) == 0xd3 && toupper (0xf3) == 0xd3))
+ {
+ fprintf (stderr, "Skipping test: no single-byte Greek locale found\n");
+ return 77;
+ }
+
+ for (int i = 0; i < 3; i++)
+ for (int j = 0; j < 3; j++)
+ {
+ static char const str[3][2] = { "\xd3", "\xf2", "\xf3" };
+ re_set_syntax (RE_ICASE);
+ memset (®ex, 0, sizeof regex);
+ s = re_compile_pattern (str[i], 1, ®ex);
+ if (s)
+ {
+ report_error ("re_compile_pattern \\x%02x failed: %s",
+ (unsigned char) str[i][0], s);
+ continue;
+ }
+ int without = re_search (®ex, str[j], 1, 0, 1, NULL);
+ regfree (®ex);
+
+ memset (®ex, 0, sizeof regex);
+ regex.fastmap = malloc (UCHAR_MAX + 1);
+ if (!regex.fastmap)
+ {
+ report_error ("malloc failed");
+ continue;
+ }
+ s = re_compile_pattern (str[i], 1, ®ex);
+ if (s)
+ {
+ report_error ("re_compile_pattern \\x%02x failed(!): %s",
+ (unsigned char) str[i][0], s);
+ continue;
+ }
+ int with = re_search (®ex, str[j], 1, 0, 1, NULL);
+
+ if (with != without)
+ report_error
+ ("fastmap mismatch: pattern = \\x%02x, string = \\x%02x,"
+ " with = %d, without = %d",
+ (unsigned char) str[i][0], (unsigned char) str[j][0],
+ with, without);
+
+ regfree (®ex);
+ }
+
+ return exit_status;
+}
diff --git a/tests/test-regex-en.c b/tests/test-regex-en.c
new file mode 100644
index 0000000000..ad3790ce10
--- /dev/null
+++ b/tests/test-regex-en.c
@@ -0,0 +1,251 @@
+/* Test regular expressions
+ Copyright 1996-2001, 2003-2026 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 <https://www.gnu.org/licenses/>. */
+
+#include <config.h>
+
+#include "regex.h"
+
+#include <locale.h>
+#include <limits.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#if HAVE_DECL_ALARM
+# include <unistd.h>
+# include <signal.h>
+#endif
+
+#include "localcharset.h"
+
+static int exit_status;
+
+static void
+report_error (char const *format, ...)
+{
+ va_list args;
+ va_start (args, format);
+ fprintf (stderr, "test-regex: ");
+ vfprintf (stderr, format, args);
+ fprintf (stderr, "\n");
+ va_end (args);
+ exit_status = 1;
+}
+
+/* Check whether it's really a UTF-8 locale.
+ On mingw, setlocale (LC_ALL, "en_US.UTF-8") succeeds but returns
+ "English_United States.1252", with locale_charset () returning "CP1252". */
+static int
+really_utf8 (void)
+{
+ return streq (locale_charset (), "UTF-8");
+}
+
+/* Tests supposed to match; copied from glibc posix/bug-regex11.c. */
+static struct
+{
+ const char *pattern;
+ const char *string;
+ int flags, nmatch;
+ regmatch_t rm[5];
+} const tests[] = {
+ /* Test for newline handling in regex. */
+ { "[^~]*~", "\nx~y", 0, 2, { { 0, 3 }, { -1, -1 } } },
+ /* Other tests. */
+ { "a(.*)b", "a b", REG_EXTENDED, 2, { { 0, 3 }, { 1, 2 } } },
+ { ".*|\\([KIO]\\)\\([^|]*\\).*|?[KIO]", "10~.~|P|K0|I10|O16|?KSb", 0, 3,
+ { { 0, 21 }, { 15, 16 }, { 16, 18 } } },
+ { ".*|\\([KIO]\\)\\([^|]*\\).*|?\\1", "10~.~|P|K0|I10|O16|?KSb", 0, 3,
+ { { 0, 21 }, { 8, 9 }, { 9, 10 } } },
+ { "^\\(a*\\)\\1\\{9\\}\\(a\\{0,9\\}\\)\\([0-9]*;.*[^a]\\2\\([0-9]\\)\\)",
+ "a1;;0a1aa2aaa3aaaa4aaaaa5aaaaaa6aaaaaaa7aaaaaaaa8aaaaaaaaa9aa2aa1a0", 0,
+ 5, { { 0, 67 }, { 0, 0 }, { 0, 1 }, { 1, 67 }, { 66, 67 } } },
+ /* Test for BRE expression anchoring. POSIX says just that this may match;
+ in glibc regex it always matched, so avoid changing it. */
+ { "\\(^\\|foo\\)bar", "bar", 0, 2, { { 0, 3 }, { -1, -1 } } },
+ { "\\(foo\\|^\\)bar", "bar", 0, 2, { { 0, 3 }, { -1, -1 } } },
+ /* In ERE this must be treated as an anchor. */
+ { "(^|foo)bar", "bar", REG_EXTENDED, 2, { { 0, 3 }, { -1, -1 } } },
+ { "(foo|^)bar", "bar", REG_EXTENDED, 2, { { 0, 3 }, { -1, -1 } } },
+ /* Here ^ cannot be treated as an anchor according to POSIX. */
+ { "(^|foo)bar", "(^|foo)bar", 0, 2, { { 0, 10 }, { -1, -1 } } },
+ { "(foo|^)bar", "(foo|^)bar", 0, 2, { { 0, 10 }, { -1, -1 } } },
+ /* More tests on backreferences. */
+ { "()\\1", "x", REG_EXTENDED, 2, { { 0, 0 }, { 0, 0 } } },
+ { "()x\\1", "x", REG_EXTENDED, 2, { { 0, 1 }, { 0, 0 } } },
+ { "()\\1*\\1*", "", REG_EXTENDED, 2, { { 0, 0 }, { 0, 0 } } },
+ { "([0-9]).*\\1(a*)", "7;7a6", REG_EXTENDED, 3, { { 0, 4 }, { 0, 1 }, { 3, 4 } } },
+ { "([0-9]).*\\1(a*)", "7;7a", REG_EXTENDED, 3, { { 0, 4 }, { 0, 1 }, { 3, 4 } } },
+ { "(b)()c\\1", "bcb", REG_EXTENDED, 3, { { 0, 3 }, { 0, 1 }, { 1, 1 } } },
+ { "()(b)c\\2", "bcb", REG_EXTENDED, 3, { { 0, 3 }, { 0, 0 }, { 0, 1 } } },
+ { "a(b)()c\\1", "abcb", REG_EXTENDED, 3, { { 0, 4 }, { 1, 2 }, { 2, 2 } } },
+ { "a()(b)c\\2", "abcb", REG_EXTENDED, 3, { { 0, 4 }, { 1, 1 }, { 1, 2 } } },
+ { "()(b)\\1c\\2", "bcb", REG_EXTENDED, 3, { { 0, 3 }, { 0, 0 }, { 0, 1 } } },
+ { "(b())\\2\\1", "bbbb", REG_EXTENDED, 3, { { 0, 2 }, { 0, 1 }, { 1, 1 } } },
+ { "a()(b)\\1c\\2", "abcb", REG_EXTENDED, 3, { { 0, 4 }, { 1, 1 }, { 1, 2 } } },
+ { "a()d(b)\\1c\\2", "adbcb", REG_EXTENDED, 3, { { 0, 5 }, { 1, 1 }, { 2, 3 } } },
+ { "a(b())\\2\\1", "abbbb", REG_EXTENDED, 3, { { 0, 3 }, { 1, 2 }, { 2, 2 } } },
+ { "(bb())\\2\\1", "bbbb", REG_EXTENDED, 3, { { 0, 4 }, { 0, 2 }, { 2, 2 } } },
+ { "^([^,]*),\\1,\\1$", "a,a,a", REG_EXTENDED, 2, { { 0, 5 }, { 0, 1 } } },
+ { "^([^,]*),\\1,\\1$", "ab,ab,ab", REG_EXTENDED, 2, { { 0, 8 }, { 0, 2 } } },
+ { "^([^,]*),\\1,\\1,\\1$", "abc,abc,abc,abc", REG_EXTENDED, 2,
+ { { 0, 15 }, { 0, 3 } } },
+ { "^(.?)(.?)(.?)(.?)(.?).?\\5\\4\\3\\2\\1$",
+ "level", REG_NOSUB | REG_EXTENDED, 0, { { -1, -1 } } },
+ { "^(.?)(.?)(.?)(.?)(.?)(.?)(.?)(.?)(.).?\\9\\8\\7\\6\\5\\4\\3\\2\\1$|^.?$",
+ "level", REG_NOSUB | REG_EXTENDED, 0, { { -1, -1 } } },
+ { "^(.?)(.?)(.?)(.?)(.?)(.?)(.?)(.?)(.).?\\9\\8\\7\\6\\5\\4\\3\\2\\1$|^.?$",
+ "abcdedcba", REG_EXTENDED, 1, { { 0, 9 } } },
+ { "^(.?)(.?)(.?)(.?)(.?)(.?)(.?)(.?)(.).?\\9\\8\\7\\6\\5\\4\\3\\2\\1$|^.?$",
+ "ababababa", REG_EXTENDED, 1, { { 0, 9 } } },
+ { "^(.?)(.?)(.?)(.?)(.?)(.?)(.?)(.?)(.?).?\\9\\8\\7\\6\\5\\4\\3\\2\\1$",
+ "level", REG_NOSUB | REG_EXTENDED, 0, { { -1, -1 } } },
+ { "^(.?)(.?)(.?)(.?)(.?)(.?)(.?)(.?)(.?).?\\9\\8\\7\\6\\5\\4\\3\\2\\1$",
+ "ababababa", REG_EXTENDED, 1, { { 0, 9 } } },
+ /* Test for *+ match. */
+ { "^a*+(.)", "ab", REG_EXTENDED, 2, { { 0, 2 }, { 1, 2 } } },
+ /* Test for ** match. */
+ { "^(a*)*(.)", "ab", REG_EXTENDED, 3, { { 0, 2 }, { 0, 1 }, { 1, 2 } } },
+};
+
+static void
+bug_regex11 (void)
+{
+ regex_t re;
+ regmatch_t rm[5];
+
+ for (size_t i = 0; i < sizeof (tests) / sizeof (tests[0]); ++i)
+ {
+ int err = regcomp (&re, tests[i].pattern, tests[i].flags);
+ if (err != 0)
+ {
+ char buf[500];
+ regerror (err, &re, buf, sizeof (buf));
+ report_error ("%s: regcomp %zd failed: %s", tests[i].pattern, i, buf);
+ continue;
+ }
+
+ if (regexec (&re, tests[i].string, tests[i].nmatch, rm, 0))
+ {
+ report_error ("%s: regexec %zd failed", tests[i].pattern, i);
+ regfree (&re);
+ continue;
+ }
+
+ for (int n = 0; n < tests[i].nmatch; ++n)
+ if (rm[n].rm_so != tests[i].rm[n].rm_so
+ || rm[n].rm_eo != tests[i].rm[n].rm_eo)
+ {
+ if (tests[i].rm[n].rm_so == -1 && tests[i].rm[n].rm_eo == -1)
+ break;
+ report_error ("%s: regexec %zd match failure rm[%d] %d..%d",
+ tests[i].pattern, i, n,
+ (int) rm[n].rm_so, (int) rm[n].rm_eo);
+ break;
+ }
+
+ regfree (&re);
+ }
+}
+
+int
+main (int argc, char *argv[])
+{
+ struct re_pattern_buffer regex;
+ unsigned char folded_chars[UCHAR_MAX + 1];
+ const char *s;
+ struct re_registers regs;
+
+#if HAVE_DECL_ALARM
+ /* In case a bug causes glibc to go into an infinite loop.
+ The tests should take less than 10 s on a reasonably modern CPU. */
+ int alarm_value = 1000;
+ signal (SIGALRM, SIG_DFL);
+ alarm (alarm_value);
+#endif
+
+ char const *locale = getenv ("LOCALE_EN_UTF8");
+ if (!locale)
+ locale = "en_US.utf8";
+ if (!setlocale (LC_ALL, locale))
+ {
+ fprintf (stderr, "Skipping test: locale %s absent\n", locale);
+ return 77;
+ }
+
+ /* https://sourceware.org/ml/libc-hacker/2006-09/msg00008.html
+ This test needs valgrind to catch the bug on Debian
+ GNU/Linux 3.1 x86, but it might catch the bug better
+ on other platforms and it shouldn't hurt to try the
+ test here. */
+ static char const pat[] = "insert into";
+ static char const data[] =
+ "\xFF\0\x12\xA2\xAA\xC4\xB1,K\x12\xC4\xB1*\xACK";
+ re_set_syntax (RE_SYNTAX_GREP | RE_HAT_LISTS_NOT_NEWLINE
+ | RE_ICASE);
+ memset (®ex, 0, sizeof regex);
+ s = re_compile_pattern (pat, sizeof pat - 1, ®ex);
+ if (s)
+ report_error ("%s: %s", pat, s);
+ else
+ {
+ memset (®s, 0, sizeof regs);
+ int ret = re_search (®ex, data, sizeof data - 1,
+ 0, sizeof data - 1, ®s);
+ if (ret != -1)
+ report_error ("re_search '%s' on '%s' returned %d",
+ pat, data, ret);
+ regfree (®ex);
+ free (regs.start);
+ free (regs.end);
+ }
+
+ if (really_utf8 ())
+ {
+ /* This test is from glibc bug 15078.
+ The test case is from Andreas Schwab in
+ <https://sourceware.org/ml/libc-alpha/2013-01/msg00967.html>.
+ */
+ static char const pat[] = "[^x]x";
+ static char const data[] =
+ /* <U1000><U103B><U103D><U1014><U103A><U102F><U1015><U103A> */
+ "\xe1\x80\x80"
+ "\xe1\x80\xbb"
+ "\xe1\x80\xbd"
+ "\xe1\x80\x94"
+ "\xe1\x80\xba"
+ "\xe1\x80\xaf"
+ "\xe1\x80\x95"
+ "\xe1\x80\xba"
+ "x";
+ re_set_syntax (0);
+ memset (®ex, 0, sizeof regex);
+ s = re_compile_pattern (pat, sizeof pat - 1, ®ex);
+ if (s)
+ report_error ("%s: %s", pat, s);
+ else
+ {
+ int ret = re_search (®ex, data, sizeof data - 1,
+ 0, sizeof data - 1, NULL);
+ if (ret != 0 && ret != 21)
+ report_error ("re_search '%s' on '%s' returned %d",
+ pat, data, ret);
+ regfree (®ex);
+ }
+ }
+
+ return exit_status;
+}
diff --git a/tests/test-regex-tr.c b/tests/test-regex-tr.c
new file mode 100644
index 0000000000..3c234c26dc
--- /dev/null
+++ b/tests/test-regex-tr.c
@@ -0,0 +1,107 @@
+/* Test regular expressions
+ Copyright 1996-2001, 2003-2026 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 <https://www.gnu.org/licenses/>. */
+
+#include <config.h>
+
+#include "regex.h"
+
+#include <locale.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <wctype.h>
+#if HAVE_DECL_ALARM
+# include <unistd.h>
+# include <signal.h>
+#endif
+
+#include "localcharset.h"
+
+static int exit_status;
+
+static void
+report_error (char const *format, ...)
+{
+ va_list args;
+ va_start (args, format);
+ fprintf (stderr, "test-regex: ");
+ vfprintf (stderr, format, args);
+ fprintf (stderr, "\n");
+ va_end (args);
+ exit_status = 1;
+}
+
+/* Check whether it's really a UTF-8 locale.
+ On mingw, setlocale (LC_ALL, "en_US.UTF-8") succeeds but returns
+ "English_United States.1252", with locale_charset () returning "CP1252". */
+static int
+really_utf8 (void)
+{
+ return streq (locale_charset (), "UTF-8");
+}
+
+int
+main (int argc, char **argv)
+{
+ struct re_pattern_buffer regex;
+ const char *s;
+ struct re_registers regs;
+
+#if HAVE_DECL_ALARM
+ /* In case a bug causes glibc to go into an infinite loop.
+ The tests should take less than 10 s on a reasonably modern CPU. */
+ int alarm_value = 1000;
+ signal (SIGALRM, SIG_DFL);
+ alarm (alarm_value);
+#endif
+
+ if (! (setlocale (LC_ALL, "tr_TR.UTF-8")
+ && really_utf8 ()
+ && towupper (L'i') == 0x0130 /* U+0130; see below. */))
+ {
+ fprintf (stderr, "Skipping test: no single-byte Greek locale found\n");
+ return 77;
+ }
+
+ re_set_syntax (RE_SYNTAX_GREP | RE_ICASE);
+ memset (®ex, 0, sizeof regex);
+ static char const pat[] = "i";
+ s = re_compile_pattern (pat, sizeof pat - 1, ®ex);
+ if (s)
+ report_error ("%s: %s", pat, s);
+ else
+ {
+ /* UTF-8 encoding of U+0130 LATIN CAPITAL LETTER I WITH DOT ABOVE.
+ In Turkish, this is the upper-case equivalent of ASCII "i".
+ Older versions of Gnulib failed to match "i" to U+0130 when
+ ignoring case in Turkish <https://bugs.gnu.org/43577>. */
+ static char const data[] = "\xc4\xb0";
+
+ memset (®s, 0, sizeof regs);
+ int ret =
+ re_search (®ex, data, sizeof data - 1, 0, sizeof data - 1,
+ ®s);
+ if (ret != 0)
+ report_error ("re_search '%s' on '%s' returned %d",
+ pat, data, ret);
+ regfree (®ex);
+ free (regs.start);
+ free (regs.end);
+ }
+
+ return exit_status;
+}
diff --git a/tests/test-regex.c b/tests/test-regex.c
index f059ad2f63..d5d33606eb 100644
--- a/tests/test-regex.c
+++ b/tests/test-regex.c
@@ -19,20 +19,16 @@
#include "regex.h"
#include <ctype.h>
-#include <locale.h>
#include <limits.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
-#include <wctype.h>
#if HAVE_DECL_ALARM
# include <unistd.h>
# include <signal.h>
#endif
-#include "localcharset.h"
-
static int exit_status;
static void
@@ -47,15 +43,6 @@ report_error (char const *format, ...)
exit_status = 1;
}
-/* Check whether it's really a UTF-8 locale.
- On mingw, setlocale (LC_ALL, "en_US.UTF-8") succeeds but returns
- "English_United States.1252", with locale_charset () returning "CP1252". */
-static int
-really_utf8 (void)
-{
- return streq (locale_charset (), "UTF-8");
-}
-
/* Tests supposed to match; copied from glibc posix/bug-regex11.c. */
static struct
{
@@ -181,175 +168,6 @@ main (void)
bug_regex11 ();
- if (setlocale (LC_ALL, "en_US.UTF-8"))
- {
- {
- /* https://sourceware.org/ml/libc-hacker/2006-09/msg00008.html
- This test needs valgrind to catch the bug on Debian
- GNU/Linux 3.1 x86, but it might catch the bug better
- on other platforms and it shouldn't hurt to try the
- test here. */
- static char const pat[] = "insert into";
- static char const data[] =
- "\xFF\0\x12\xA2\xAA\xC4\xB1,K\x12\xC4\xB1*\xACK";
- re_set_syntax (RE_SYNTAX_GREP | RE_HAT_LISTS_NOT_NEWLINE
- | RE_ICASE);
- memset (®ex, 0, sizeof regex);
- s = re_compile_pattern (pat, sizeof pat - 1, ®ex);
- if (s)
- report_error ("%s: %s", pat, s);
- else
- {
- memset (®s, 0, sizeof regs);
- int ret = re_search (®ex, data, sizeof data - 1,
- 0, sizeof data - 1, ®s);
- if (ret != -1)
- report_error ("re_search '%s' on '%s' returned %d",
- pat, data, ret);
- regfree (®ex);
- free (regs.start);
- free (regs.end);
- }
- }
-
- if (really_utf8 ())
- {
- /* This test is from glibc bug 15078.
- The test case is from Andreas Schwab in
- <https://sourceware.org/ml/libc-alpha/2013-01/msg00967.html>.
- */
- static char const pat[] = "[^x]x";
- static char const data[] =
- /* <U1000><U103B><U103D><U1014><U103A><U102F><U1015><U103A> */
- "\xe1\x80\x80"
- "\xe1\x80\xbb"
- "\xe1\x80\xbd"
- "\xe1\x80\x94"
- "\xe1\x80\xba"
- "\xe1\x80\xaf"
- "\xe1\x80\x95"
- "\xe1\x80\xba"
- "x";
- re_set_syntax (0);
- memset (®ex, 0, sizeof regex);
- s = re_compile_pattern (pat, sizeof pat - 1, ®ex);
- if (s)
- report_error ("%s: %s", pat, s);
- else
- {
- int ret = re_search (®ex, data, sizeof data - 1,
- 0, sizeof data - 1, NULL);
- if (ret != 0 && ret != 21)
- report_error ("re_search '%s' on '%s' returned %d",
- pat, data, ret);
- regfree (®ex);
- }
- }
-
- if (! setlocale (LC_ALL, "C"))
- {
- report_error ("setlocale \"C\" failed");
- return exit_status;
- }
- }
-
- /* Test for glibc bug 20381
- <https://sourceware.org/bugzilla/show_bug.cgi?id=20381>. */
- if (setlocale (LC_ALL, "el_GR.iso88597")
- || setlocale (LC_ALL, "el_GR.ISO8859-7")
- || setlocale (LC_ALL, "el_GR.iso8859-7"))
- {
- /* Check this only in Greek locales that seem to be working.
- In macOS 26, for example, setlocale (LC_ALL, "el_GR.ISO8859-7")
- succeed but acts like the C locale. */
- if (toupper (0xf2) == 0xd3 && toupper (0xf3) == 0xd3)
- for (int i = 0; i < 3; i++)
- for (int j = 0; j < 3; j++)
- {
- static char const str[3][2] = { "\xd3", "\xf2", "\xf3" };
- re_set_syntax (RE_ICASE);
- memset (®ex, 0, sizeof regex);
- s = re_compile_pattern (str[i], 1, ®ex);
- if (s)
- {
- report_error ("re_compile_pattern \\x%02x failed: %s",
- (unsigned char) str[i][0], s);
- continue;
- }
- int without = re_search (®ex, str[j], 1, 0, 1, NULL);
- regfree (®ex);
-
- memset (®ex, 0, sizeof regex);
- regex.fastmap = malloc (UCHAR_MAX + 1);
- if (!regex.fastmap)
- {
- report_error ("malloc failed");
- continue;
- }
- s = re_compile_pattern (str[i], 1, ®ex);
- if (s)
- {
- report_error ("re_compile_pattern \\x%02x failed(!): %s",
- (unsigned char) str[i][0], s);
- continue;
- }
- int with = re_search (®ex, str[j], 1, 0, 1, NULL);
-
- if (with != without)
- report_error
- ("fastmap mismatch: pattern = \\x%02x, string = \\x%02x,"
- " with = %d, without = %d",
- (unsigned char) str[i][0], (unsigned char) str[j][0],
- with, without);
-
- regfree (®ex);
- }
-
- if (! setlocale (LC_ALL, "C"))
- {
- report_error ("setlocale \"C\" failed");
- return exit_status;
- }
- }
-
- if (setlocale (LC_ALL, "tr_TR.UTF-8"))
- {
- if (really_utf8 () && towupper (L'i') == 0x0130 /* U+0130; see below. */)
- {
- re_set_syntax (RE_SYNTAX_GREP | RE_ICASE);
- memset (®ex, 0, sizeof regex);
- static char const pat[] = "i";
- s = re_compile_pattern (pat, sizeof pat - 1, ®ex);
- if (s)
- report_error ("%s: %s", pat, s);
- else
- {
- /* UTF-8 encoding of U+0130 LATIN CAPITAL LETTER I WITH DOT ABOVE.
- In Turkish, this is the upper-case equivalent of ASCII "i".
- Older versions of Gnulib failed to match "i" to U+0130 when
- ignoring case in Turkish <https://bugs.gnu.org/43577>. */
- static char const data[] = "\xc4\xb0";
-
- memset (®s, 0, sizeof regs);
- int ret =
- re_search (®ex, data, sizeof data - 1, 0, sizeof data - 1,
- ®s);
- if (ret != 0)
- report_error ("re_search '%s' on '%s' returned %d",
- pat, data, ret);
- regfree (®ex);
- free (regs.start);
- free (regs.end);
- }
- }
-
- if (! setlocale (LC_ALL, "C"))
- {
- report_error ("setlocale \"C\" failed");
- return exit_status;
- }
- }
-
/* This test is from glibc bug 3957, reported by Andrew Mackey. */
re_set_syntax (RE_SYNTAX_EGREP | RE_HAT_LISTS_NOT_NEWLINE);
memset (®ex, 0, sizeof regex);
--
2.54.0