summaryrefslogtreecommitdiff
path: root/backport-Add-TEST_COMPARE_STRING_WIDE-to-support-check.h.patch
diff options
context:
space:
mode:
authorCoprDistGit <infra@openeuler.org>2024-08-03 06:28:41 +0000
committerCoprDistGit <infra@openeuler.org>2024-08-03 06:28:41 +0000
commitd20db0561a6a36f914fde030512503b114ef9a0c (patch)
treed4e5e3494d95c269a1cee6195f11bf3201bcadbf /backport-Add-TEST_COMPARE_STRING_WIDE-to-support-check.h.patch
parent016343d99b1b269d7246ef1e143d4b54914433d4 (diff)
Diffstat (limited to 'backport-Add-TEST_COMPARE_STRING_WIDE-to-support-check.h.patch')
-rw-r--r--backport-Add-TEST_COMPARE_STRING_WIDE-to-support-check.h.patch757
1 files changed, 757 insertions, 0 deletions
diff --git a/backport-Add-TEST_COMPARE_STRING_WIDE-to-support-check.h.patch b/backport-Add-TEST_COMPARE_STRING_WIDE-to-support-check.h.patch
new file mode 100644
index 0000000..e97367b
--- /dev/null
+++ b/backport-Add-TEST_COMPARE_STRING_WIDE-to-support-check.h.patch
@@ -0,0 +1,757 @@
+From de82cb0da4b8fa5b3d56c457438d2568c67ab1b1 Mon Sep 17 00:00:00 2001
+From: Joseph Myers <joseph@codesourcery.com>
+Date: Tue, 12 Oct 2021 13:48:39 +0000
+Subject: [PATCH] Add TEST_COMPARE_STRING_WIDE to support/check.h
+
+I'd like to be able to test narrow and wide string interfaces, with
+the narrow string tests using TEST_COMPARE_STRING and the wide string
+tests using something analogous (possibly generated using macros from
+a common test template for both the narrow and wide string tests where
+appropriate).
+
+Add such a TEST_COMPARE_STRING_WIDE, along with functions
+support_quote_blob_wide and support_test_compare_string_wide that it
+builds on. Those functions are built using macros from common
+templates shared by the narrow and wide string implementations, though
+I didn't do that for the tests of test functions. In
+support_quote_blob_wide, I chose to use the \x{} delimited escape
+sequence syntax proposed for C2X in N2785, rather than e.g. trying to
+generate the end of a string and the start of a new string when
+ambiguity would result from undelimited \x (when the next character
+after such an escape sequence is valid hex) or forcing an escape
+sequence to be used for the next character in the case of such
+ambiguity.
+
+Tested for x86_64.
+Conflict:NA
+Reference:https://sourceware.org/git/?p=glibc.git;a=commit;h=de82cb0da4b8fa5b3d56c457438d2568c67ab1b1
+---
+ support/Makefile | 4 +
+ support/check.h | 15 +++
+ support/support.h | 6 ++
+ support/support_quote_blob.c | 71 ++------------
+ support/support_quote_blob_main.c | 88 +++++++++++++++++
+ support/support_quote_blob_wide.c | 24 +++++
+ support/support_test_compare_string.c | 83 ++--------------
+ support/support_test_compare_string_main.c | 94 ++++++++++++++++++
+ support/support_test_compare_string_wide.c | 28 ++++++
+ support/tst-support_quote_blob_wide.c | 66 +++++++++++++
+ support/tst-test_compare_string_wide.c | 107 +++++++++++++++++++++
+ 11 files changed, 448 insertions(+), 138 deletions(-)
+ create mode 100644 support/support_quote_blob_main.c
+ create mode 100644 support/support_quote_blob_wide.c
+ create mode 100644 support/support_test_compare_string_main.c
+ create mode 100644 support/support_test_compare_string_wide.c
+ create mode 100644 support/tst-support_quote_blob_wide.c
+ create mode 100644 support/tst-test_compare_string_wide.c
+
+diff --git a/support/Makefile b/support/Makefile
+index fd27c8451e..7f03950914 100644
+--- a/support/Makefile
++++ b/support/Makefile
+@@ -71,6 +71,7 @@ libsupport-routines = \
+ support_openpty \
+ support_paths \
+ support_quote_blob \
++ support_quote_blob_wide \
+ support_quote_string \
+ support_record_failure \
+ support_run_diff \
+@@ -84,6 +85,7 @@ libsupport-routines = \
+ support_test_compare_blob \
+ support_test_compare_failure \
+ support_test_compare_string \
++ support_test_compare_string_wide \
+ support_test_main \
+ support_test_verify_impl \
+ support_wait_for_thread_exit \
+@@ -270,11 +272,13 @@ tests = \
+ tst-support-open-dev-null-range \
+ tst-support-process_state \
+ tst-support_quote_blob \
++ tst-support_quote_blob_wide \
+ tst-support_quote_string \
+ tst-support_record_failure \
+ tst-test_compare \
+ tst-test_compare_blob \
+ tst-test_compare_string \
++ tst-test_compare_string_wide \
+ tst-timespec \
+ tst-xreadlink \
+ tst-xsigstack \
+diff --git a/support/check.h b/support/check.h
+index 83662b2d10..9b1844352f 100644
+--- a/support/check.h
++++ b/support/check.h
+@@ -20,6 +20,7 @@
+ #define SUPPORT_CHECK_H
+
+ #include <sys/cdefs.h>
++#include <stddef.h>
+
+ __BEGIN_DECLS
+
+@@ -171,11 +172,25 @@ void support_test_compare_blob (const void *left,
+ (support_test_compare_string (left, right, __FILE__, __LINE__, \
+ #left, #right))
+
++/* Compare the wide strings LEFT and RIGHT and report a test failure
++ if they are different. Also report failure if one of the arguments
++ is a null pointer and the other is not. The strings should be
++ reasonably short because on mismatch, both are printed. */
++#define TEST_COMPARE_STRING_WIDE(left, right) \
++ (support_test_compare_string_wide (left, right, __FILE__, __LINE__, \
++ #left, #right))
++
+ void support_test_compare_string (const char *left, const char *right,
+ const char *file, int line,
+ const char *left_expr,
+ const char *right_expr);
+
++void support_test_compare_string_wide (const wchar_t *left,
++ const wchar_t *right,
++ const char *file, int line,
++ const char *left_expr,
++ const char *right_expr);
++
+ /* Internal function called by the test driver. */
+ int support_report_failure (int status)
+ __attribute__ ((weak, warn_unused_result));
+diff --git a/support/support.h b/support/support.h
+index 837a806531..0ee454da6d 100644
+--- a/support/support.h
++++ b/support/support.h
+@@ -73,6 +73,12 @@ void support_write_file_string (const char *path, const char *contents);
+ the result). */
+ char *support_quote_blob (const void *blob, size_t length);
+
++/* Quote the contents of the wide character array starting at BLOB, of
++ LENGTH wide characters, in such a way that the result string can be
++ included in a C wide string literal (in single/double quotes,
++ without putting the quotes into the result). */
++char *support_quote_blob_wide (const void *blob, size_t length);
++
+ /* Quote the contents of the string, in such a way that the result
+ string can be included in a C literal (in single/double quotes,
+ without putting the quotes into the result). */
+diff --git a/support/support_quote_blob.c b/support/support_quote_blob.c
+index b5e70125f1..611980c9a2 100644
+--- a/support/support_quote_blob.c
++++ b/support/support_quote_blob.c
+@@ -1,4 +1,4 @@
+-/* Quote a blob so that it can be used in C literals.
++/* Quote a narrow string blob so that it can be used in C literals.
+ Copyright (C) 2018-2021 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+@@ -16,68 +16,9 @@
+ License along with the GNU C Library; if not, see
+ <https://www.gnu.org/licenses/>. */
+
+-#include <support/support.h>
+-#include <support/xmemstream.h>
++#define CHAR unsigned char
++#define L_(C) C
++#define SUPPORT_QUOTE_BLOB support_quote_blob
++#define WIDE 0
+
+-char *
+-support_quote_blob (const void *blob, size_t length)
+-{
+- struct xmemstream out;
+- xopen_memstream (&out);
+-
+- const unsigned char *p = blob;
+- for (size_t i = 0; i < length; ++i)
+- {
+- unsigned char ch = p[i];
+-
+- /* Use C backslash escapes for those control characters for
+- which they are defined. */
+- switch (ch)
+- {
+- case '\a':
+- putc_unlocked ('\\', out.out);
+- putc_unlocked ('a', out.out);
+- break;
+- case '\b':
+- putc_unlocked ('\\', out.out);
+- putc_unlocked ('b', out.out);
+- break;
+- case '\f':
+- putc_unlocked ('\\', out.out);
+- putc_unlocked ('f', out.out);
+- break;
+- case '\n':
+- putc_unlocked ('\\', out.out);
+- putc_unlocked ('n', out.out);
+- break;
+- case '\r':
+- putc_unlocked ('\\', out.out);
+- putc_unlocked ('r', out.out);
+- break;
+- case '\t':
+- putc_unlocked ('\\', out.out);
+- putc_unlocked ('t', out.out);
+- break;
+- case '\v':
+- putc_unlocked ('\\', out.out);
+- putc_unlocked ('v', out.out);
+- break;
+- case '\\':
+- case '\'':
+- case '\"':
+- putc_unlocked ('\\', out.out);
+- putc_unlocked (ch, out.out);
+- break;
+- default:
+- if (ch < ' ' || ch > '~')
+- /* Use octal sequences because they are fixed width,
+- unlike hexadecimal sequences. */
+- fprintf (out.out, "\\%03o", ch);
+- else
+- putc_unlocked (ch, out.out);
+- }
+- }
+-
+- xfclose_memstream (&out);
+- return out.buffer;
+-}
++#include "support_quote_blob_main.c"
+diff --git a/support/support_quote_blob_main.c b/support/support_quote_blob_main.c
+new file mode 100644
+index 0000000000..19ccfad593
+--- /dev/null
++++ b/support/support_quote_blob_main.c
+@@ -0,0 +1,88 @@
++/* Quote a blob so that it can be used in C literals.
++ Copyright (C) 2018-2021 Free Software Foundation, Inc.
++ This file is part of the GNU C Library.
++
++ The GNU C Library is free software; you can redistribute it and/or
++ modify it under the terms of the GNU Lesser General Public
++ License as published by the Free Software Foundation; either
++ version 2.1 of the License, or (at your option) any later version.
++
++ The GNU C Library 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
++ Lesser General Public License for more details.
++
++ You should have received a copy of the GNU Lesser General Public
++ License along with the GNU C Library; if not, see
++ <https://www.gnu.org/licenses/>. */
++
++#include <support/support.h>
++#include <support/xmemstream.h>
++
++char *
++SUPPORT_QUOTE_BLOB (const void *blob, size_t length)
++{
++ struct xmemstream out;
++ xopen_memstream (&out);
++
++ const CHAR *p = blob;
++ for (size_t i = 0; i < length; ++i)
++ {
++ CHAR ch = p[i];
++
++ /* Use C backslash escapes for those control characters for
++ which they are defined. */
++ switch (ch)
++ {
++ case L_('\a'):
++ putc_unlocked ('\\', out.out);
++ putc_unlocked ('a', out.out);
++ break;
++ case L_('\b'):
++ putc_unlocked ('\\', out.out);
++ putc_unlocked ('b', out.out);
++ break;
++ case L_('\f'):
++ putc_unlocked ('\\', out.out);
++ putc_unlocked ('f', out.out);
++ break;
++ case L_('\n'):
++ putc_unlocked ('\\', out.out);
++ putc_unlocked ('n', out.out);
++ break;
++ case L_('\r'):
++ putc_unlocked ('\\', out.out);
++ putc_unlocked ('r', out.out);
++ break;
++ case L_('\t'):
++ putc_unlocked ('\\', out.out);
++ putc_unlocked ('t', out.out);
++ break;
++ case L_('\v'):
++ putc_unlocked ('\\', out.out);
++ putc_unlocked ('v', out.out);
++ break;
++ case L_('\\'):
++ case L_('\''):
++ case L_('\"'):
++ putc_unlocked ('\\', out.out);
++ putc_unlocked (ch, out.out);
++ break;
++ default:
++ if (ch < L_(' ') || ch > L_('~'))
++ /* For narrow characters, use octal sequences because they
++ are fixed width, unlike hexadecimal sequences. For
++ wide characters, use N2785 delimited escape
++ sequences. */
++ if (WIDE)
++ fprintf (out.out, "\\x{%x}", (unsigned int) ch);
++ else
++ fprintf (out.out, "\\%03o", (unsigned int) ch);
++ else
++ putc_unlocked (ch, out.out);
++ }
++ }
++
++ xfclose_memstream (&out);
++ return out.buffer;
++}
+diff --git a/support/support_quote_blob_wide.c b/support/support_quote_blob_wide.c
+new file mode 100644
+index 0000000000..c451ed889c
+--- /dev/null
++++ b/support/support_quote_blob_wide.c
+@@ -0,0 +1,24 @@
++/* Quote a wide string blob so that it can be used in C literals.
++ Copyright (C) 2018-2021 Free Software Foundation, Inc.
++ This file is part of the GNU C Library.
++
++ The GNU C Library is free software; you can redistribute it and/or
++ modify it under the terms of the GNU Lesser General Public
++ License as published by the Free Software Foundation; either
++ version 2.1 of the License, or (at your option) any later version.
++
++ The GNU C Library 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
++ Lesser General Public License for more details.
++
++ You should have received a copy of the GNU Lesser General Public
++ License along with the GNU C Library; if not, see
++ <https://www.gnu.org/licenses/>. */
++
++#define CHAR wchar_t
++#define L_(C) L ## C
++#define SUPPORT_QUOTE_BLOB support_quote_blob_wide
++#define WIDE 1
++
++#include "support_quote_blob_main.c"
+diff --git a/support/support_test_compare_string.c b/support/support_test_compare_string.c
+index cbeaf7b1ee..12bafe43d4 100644
+--- a/support/support_test_compare_string.c
++++ b/support/support_test_compare_string.c
+@@ -16,76 +16,13 @@
+ License along with the GNU C Library; if not, see
+ <https://www.gnu.org/licenses/>. */
+
+-#include <stdio.h>
+-#include <stdlib.h>
+-#include <string.h>
+-#include <support/check.h>
+-#include <support/support.h>
+-#include <support/xmemstream.h>
+-
+-static void
+-report_length (const char *what, const char *str, size_t length)
+-{
+- if (str == NULL)
+- printf (" %s string: NULL\n", what);
+- else
+- printf (" %s string: %zu bytes\n", what, length);
+-}
+-
+-static void
+-report_string (const char *what, const unsigned char *blob,
+- size_t length, const char *expr)
+-{
+- if (length > 0)
+- {
+- printf (" %s (evaluated from %s):\n", what, expr);
+- char *quoted = support_quote_blob (blob, length);
+- printf (" \"%s\"\n", quoted);
+- free (quoted);
+-
+- fputs (" ", stdout);
+- for (size_t i = 0; i < length; ++i)
+- printf (" %02X", blob[i]);
+- putc ('\n', stdout);
+- }
+-}
+-
+-static size_t
+-string_length_or_zero (const char *str)
+-{
+- if (str == NULL)
+- return 0;
+- else
+- return strlen (str);
+-}
+-
+-void
+-support_test_compare_string (const char *left, const char *right,
+- const char *file, int line,
+- const char *left_expr, const char *right_expr)
+-{
+- /* Two null pointers are accepted. */
+- if (left == NULL && right == NULL)
+- return;
+-
+- size_t left_length = string_length_or_zero (left);
+- size_t right_length = string_length_or_zero (right);
+-
+- if (left_length != right_length || left == NULL || right == NULL
+- || memcmp (left, right, left_length) != 0)
+- {
+- support_record_failure ();
+- printf ("%s:%d: error: string comparison failed\n", file, line);
+- if (left_length == right_length && right != NULL && left != NULL)
+- printf (" string length: %zu bytes\n", left_length);
+- else
+- {
+- report_length ("left", left, left_length);
+- report_length ("right", right, right_length);
+- }
+- report_string ("left", (const unsigned char *) left,
+- left_length, left_expr);
+- report_string ("right", (const unsigned char *) right,
+- right_length, right_expr);
+- }
+-}
++#define CHAR char
++#define UCHAR unsigned char
++#define LPREFIX ""
++#define STRLEN strlen
++#define MEMCMP memcmp
++#define SUPPORT_QUOTE_BLOB support_quote_blob
++#define SUPPORT_TEST_COMPARE_STRING support_test_compare_string
++#define WIDE 0
++
++#include "support_test_compare_string_main.c"
+diff --git a/support/support_test_compare_string_main.c b/support/support_test_compare_string_main.c
+new file mode 100644
+index 0000000000..0edc0ca97d
+--- /dev/null
++++ b/support/support_test_compare_string_main.c
+@@ -0,0 +1,94 @@
++/* Check two strings for equality.
++ Copyright (C) 2018-2021 Free Software Foundation, Inc.
++ This file is part of the GNU C Library.
++
++ The GNU C Library is free software; you can redistribute it and/or
++ modify it under the terms of the GNU Lesser General Public
++ License as published by the Free Software Foundation; either
++ version 2.1 of the License, or (at your option) any later version.
++
++ The GNU C Library 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
++ Lesser General Public License for more details.
++
++ You should have received a copy of the GNU Lesser General Public
++ License along with the GNU C Library; if not, see
++ <https://www.gnu.org/licenses/>. */
++
++#include <stdio.h>
++#include <stdlib.h>
++#include <string.h>
++#include <wchar.h>
++#include <support/check.h>
++#include <support/support.h>
++#include <support/xmemstream.h>
++
++static void
++report_length (const char *what, const CHAR *str, size_t length)
++{
++ if (str == NULL)
++ printf (" %s string: NULL\n", what);
++ else
++ printf (" %s string: %zu %s\n", what, length,
++ WIDE ? "wide characters" : "bytes");
++}
++
++static void
++report_string (const char *what, const UCHAR *blob,
++ size_t length, const char *expr)
++{
++ if (length > 0)
++ {
++ printf (" %s (evaluated from %s):\n", what, expr);
++ char *quoted = SUPPORT_QUOTE_BLOB (blob, length);
++ printf (" %s\"%s\"\n", LPREFIX, quoted);
++ free (quoted);
++
++ fputs (" ", stdout);
++ for (size_t i = 0; i < length; ++i)
++ printf (" %02X", (unsigned int) blob[i]);
++ putc ('\n', stdout);
++ }
++}
++
++static size_t
++string_length_or_zero (const CHAR *str)
++{
++ if (str == NULL)
++ return 0;
++ else
++ return STRLEN (str);
++}
++
++void
++SUPPORT_TEST_COMPARE_STRING (const CHAR *left, const CHAR *right,
++ const char *file, int line,
++ const char *left_expr, const char *right_expr)
++{
++ /* Two null pointers are accepted. */
++ if (left == NULL && right == NULL)
++ return;
++
++ size_t left_length = string_length_or_zero (left);
++ size_t right_length = string_length_or_zero (right);
++
++ if (left_length != right_length || left == NULL || right == NULL
++ || MEMCMP (left, right, left_length) != 0)
++ {
++ support_record_failure ();
++ printf ("%s:%d: error: string comparison failed\n", file, line);
++ if (left_length == right_length && right != NULL && left != NULL)
++ printf (" string length: %zu %s\n", left_length,
++ WIDE ? "wide characters" : "bytes");
++ else
++ {
++ report_length ("left", left, left_length);
++ report_length ("right", right, right_length);
++ }
++ report_string ("left", (const UCHAR *) left,
++ left_length, left_expr);
++ report_string ("right", (const UCHAR *) right,
++ right_length, right_expr);
++ }
++}
+diff --git a/support/support_test_compare_string_wide.c b/support/support_test_compare_string_wide.c
+new file mode 100644
+index 0000000000..88b560b142
+--- /dev/null
++++ b/support/support_test_compare_string_wide.c
+@@ -0,0 +1,28 @@
++/* Check two wide strings for equality.
++ Copyright (C) 2018-2021 Free Software Foundation, Inc.
++ This file is part of the GNU C Library.
++
++ The GNU C Library is free software; you can redistribute it and/or
++ modify it under the terms of the GNU Lesser General Public
++ License as published by the Free Software Foundation; either
++ version 2.1 of the License, or (at your option) any later version.
++
++ The GNU C Library 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
++ Lesser General Public License for more details.
++
++ You should have received a copy of the GNU Lesser General Public
++ License along with the GNU C Library; if not, see
++ <https://www.gnu.org/licenses/>. */
++
++#define CHAR wchar_t
++#define UCHAR wchar_t
++#define LPREFIX "L"
++#define STRLEN wcslen
++#define MEMCMP wmemcmp
++#define SUPPORT_QUOTE_BLOB support_quote_blob_wide
++#define SUPPORT_TEST_COMPARE_STRING support_test_compare_string_wide
++#define WIDE 1
++
++#include "support_test_compare_string_main.c"
+diff --git a/support/tst-support_quote_blob_wide.c b/support/tst-support_quote_blob_wide.c
+new file mode 100644
+index 0000000000..ea71a1f7f8
+--- /dev/null
++++ b/support/tst-support_quote_blob_wide.c
+@@ -0,0 +1,66 @@
++/* Test the support_quote_blob_wide function.
++ Copyright (C) 2018-2021 Free Software Foundation, Inc.
++ This file is part of the GNU C Library.
++
++ The GNU C Library is free software; you can redistribute it and/or
++ modify it under the terms of the GNU Lesser General Public
++ License as published by the Free Software Foundation; either
++ version 2.1 of the License, or (at your option) any later version.
++
++ The GNU C Library 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
++ Lesser General Public License for more details.
++
++ You should have received a copy of the GNU Lesser General Public
++ License along with the GNU C Library; if not, see
++ <https://www.gnu.org/licenses/>. */
++
++#include <support/check.h>
++#include <support/support.h>
++#include <string.h>
++#include <stdlib.h>
++
++static int
++do_test (void)
++{
++ /* Check handling of the empty blob, both with and without trailing
++ NUL byte. */
++ char *p = support_quote_blob_wide (L"", 0);
++ TEST_COMPARE (strlen (p), 0);
++ free (p);
++ p = support_quote_blob_wide (L"X", 0);
++ TEST_COMPARE (strlen (p), 0);
++ free (p);
++
++ /* Check escaping of backslash-escaped characters, and lack of
++ escaping for other shell meta-characters. */
++ p = support_quote_blob_wide (L"$()*?`@[]{}~\'\"X", 14);
++ TEST_COMPARE (strcmp (p, "$()*?`@[]{}~\\'\\\""), 0);
++ free (p);
++
++ /* Check lack of escaping for letters and digits. */
++#define LETTERS_AND_DIGTS \
++ "abcdefghijklmnopqrstuvwxyz" \
++ "ABCDEFGHIJKLMNOPQRSTUVWXYZ" \
++ "0123456789"
++#define CONCATX(X, Y) X ## Y
++#define CONCAT(X, Y) CONCATX (X, Y)
++#define WLETTERS_AND_DIGTS CONCAT (L, LETTERS_AND_DIGTS)
++ p = support_quote_blob_wide (WLETTERS_AND_DIGTS "@", 2 * 26 + 10);
++ TEST_COMPARE (strcmp (p, LETTERS_AND_DIGTS), 0);
++ free (p);
++
++ /* Check escaping of control characters and other non-printable
++ characters. */
++ p = support_quote_blob_wide (L"\r\n\t\a\b\f\v\1\177\200\377"
++ "\x123\x76543210\xfedcba98\0@", 17);
++ TEST_COMPARE (strcmp (p, "\\r\\n\\t\\a\\b\\f\\v\\x{1}"
++ "\\x{7f}\\x{80}\\x{ff}\\x{123}\\x{76543210}"
++ "\\x{fedcba98}\\x{0}@\\x{0}"), 0);
++ free (p);
++
++ return 0;
++}
++
++#include <support/test-driver.c>
+diff --git a/support/tst-test_compare_string_wide.c b/support/tst-test_compare_string_wide.c
+new file mode 100644
+index 0000000000..548f7dcdc6
+--- /dev/null
++++ b/support/tst-test_compare_string_wide.c
+@@ -0,0 +1,107 @@
++/* Basic test for the TEST_COMPARE_STRING_WIDE macro.
++ Copyright (C) 2018-2021 Free Software Foundation, Inc.
++ This file is part of the GNU C Library.
++
++ The GNU C Library is free software; you can redistribute it and/or
++ modify it under the terms of the GNU Lesser General Public
++ License as published by the Free Software Foundation; either
++ version 2.1 of the License, or (at your option) any later version.
++
++ The GNU C Library 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
++ Lesser General Public License for more details.
++
++ You should have received a copy of the GNU Lesser General Public
++ License along with the GNU C Library; if not, see
++ <https://www.gnu.org/licenses/>. */
++
++#include <string.h>
++#include <support/check.h>
++#include <support/capture_subprocess.h>
++
++static void
++subprocess (void *closure)
++{
++ /* These tests should fail. They were chosen to cover differences
++ in length (with the same contents), single-bit mismatches, and
++ mismatching null pointers. */
++ TEST_COMPARE_STRING_WIDE (L"", NULL); /* Line 29. */
++ TEST_COMPARE_STRING_WIDE (L"X", L""); /* Line 30. */
++ TEST_COMPARE_STRING_WIDE (NULL, L"X"); /* Line 31. */
++ TEST_COMPARE_STRING_WIDE (L"abcd", L"abcD"); /* Line 32. */
++ TEST_COMPARE_STRING_WIDE (L"abcd", NULL); /* Line 33. */
++ TEST_COMPARE_STRING_WIDE (NULL, L"abcd"); /* Line 34. */
++}
++
++/* Same contents, different addresses. */
++wchar_t buffer_abc_1[] = L"abc";
++wchar_t buffer_abc_2[] = L"abc";
++
++static int
++do_test (void)
++{
++ /* This should succeed. Even if the pointers and array contents are
++ different, zero-length inputs are not different. */
++ TEST_COMPARE_STRING_WIDE (NULL, NULL);
++ TEST_COMPARE_STRING_WIDE (L"", L"");
++ TEST_COMPARE_STRING_WIDE (buffer_abc_1, buffer_abc_2);
++ TEST_COMPARE_STRING_WIDE (buffer_abc_1, L"abc");
++
++ struct support_capture_subprocess proc = support_capture_subprocess
++ (&subprocess, NULL);
++
++ /* Discard the reported error. */
++ support_record_failure_reset ();
++
++ puts ("info: *** subprocess output starts ***");
++ fputs (proc.out.buffer, stdout);
++ puts ("info: *** subprocess output ends ***");
++
++ TEST_VERIFY
++ (strcmp (proc.out.buffer,
++"tst-test_compare_string_wide.c:29: error: string comparison failed\n"
++" left string: 0 wide characters\n"
++" right string: NULL\n"
++"tst-test_compare_string_wide.c:30: error: string comparison failed\n"
++" left string: 1 wide characters\n"
++" right string: 0 wide characters\n"
++" left (evaluated from L\"X\"):\n"
++" L\"X\"\n"
++" 58\n"
++"tst-test_compare_string_wide.c:31: error: string comparison failed\n"
++" left string: NULL\n"
++" right string: 1 wide characters\n"
++" right (evaluated from L\"X\"):\n"
++" L\"X\"\n"
++" 58\n"
++"tst-test_compare_string_wide.c:32: error: string comparison failed\n"
++" string length: 4 wide characters\n"
++" left (evaluated from L\"abcd\"):\n"
++" L\"abcd\"\n"
++" 61 62 63 64\n"
++" right (evaluated from L\"abcD\"):\n"
++" L\"abcD\"\n"
++" 61 62 63 44\n"
++"tst-test_compare_string_wide.c:33: error: string comparison failed\n"
++" left string: 4 wide characters\n"
++" right string: NULL\n"
++" left (evaluated from L\"abcd\"):\n"
++" L\"abcd\"\n"
++" 61 62 63 64\n"
++"tst-test_compare_string_wide.c:34: error: string comparison failed\n"
++" left string: NULL\n"
++" right string: 4 wide characters\n"
++" right (evaluated from L\"abcd\"):\n"
++" L\"abcd\"\n"
++" 61 62 63 64\n"
++ ) == 0);
++
++ /* Check that there is no output on standard error. */
++ support_capture_subprocess_check (&proc, "TEST_COMPARE_STRING_WIDE",
++ 0, sc_allow_stdout);
++
++ return 0;
++}
++
++#include <support/test-driver.c>
+--
+2.28.0.windows.1
+