ldbl-128ibm-compat: Add wide character printing functions

Similarly to what was done for regular character printing functions,
this patch uses the new mode mask, PRINTF_LDBL_USES_FLOAT128, in the
'mode' argument of the wide characters printing function,
__vfwprintf_internal (which is also extended to support printing
floating-point values with IEEE binary128, by saving floating-point
values into variables of type __float128 and adjusting the parameters to
__printf_fp and __printf_fphex as if it was a call from a wide-character
version of strfromf128 (even though such version does not exist)).

Tested for powerpc64le.

Reviewed-By: Paul E. Murphy <murphyp@linux.ibm.com>
This commit is contained in:
Gabriel F. T. Gomes 2019-07-11 11:46:51 -03:00
parent 421a1d34bf
commit 1771a5cf0e
11 changed files with 321 additions and 1 deletions

View File

@ -11,7 +11,13 @@ ldbl-extra-routines += printf_size \
vfprintf \
vprintf \
vsnprintf \
vsprintf
vsprintf \
fwprintf \
swprintf \
wprintf \
vfwprintf \
vswprintf \
vwprintf
# Printing long double values with IEEE binary128 format reuses part
# of the internal float128 implementation (__printf_fp, __printf_fphex,
@ -19,6 +25,7 @@ ldbl-extra-routines += printf_size \
# the following functions, must have -mfloat128 and -mabi=ibmlongdouble
# passed to the compiler.
CFLAGS-vfprintf-internal.c += -mfloat128 -mabi=ibmlongdouble
CFLAGS-vfwprintf-internal.c += -mfloat128 -mabi=ibmlongdouble
# Basic tests for the implementation of long double with IEEE binary128
# format and for the related redirections in installed headers.
@ -26,6 +33,10 @@ tests-internal += test-printf-ieee128 test-printf-ibm128
CFLAGS-test-printf-ieee128.c += -mfloat128 -mabi=ieeelongdouble -Wno-psabi
CFLAGS-test-printf-ibm128.c += -mabi=ibmlongdouble -Wno-psabi
tests-internal += test-wprintf-ieee128 test-wprintf-ibm128
CFLAGS-test-wprintf-ieee128.c += -mfloat128 -mabi=ieeelongdouble -Wno-psabi
CFLAGS-test-wprintf-ibm128.c += -mabi=ibmlongdouble -Wno-psabi
tests-internal += test-printf-size-ieee128 test-printf-size-ibm128
CFLAGS-test-printf-size-ieee128.c += -mfloat128 -mabi=ieeelongdouble -Wno-psabi
CFLAGS-test-printf-size-ibm128.c += -mabi=ibmlongdouble -Wno-psabi

View File

@ -134,5 +134,13 @@ libc {
__vprintfieee128;
__vsnprintfieee128;
__vsprintfieee128;
__fwprintfieee128;
__swprintfieee128;
__wprintfieee128;
__vfwprintfieee128;
__vswprintfieee128;
__vwprintfieee128;
}
}

View File

@ -0,0 +1,35 @@
/* Wrapper for fwprintf. IEEE128 version.
Copyright (C) 2019 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
<http://www.gnu.org/licenses/>. */
#include <stdarg.h>
#include <libio/libioP.h>
extern int
___ieee128_fwprintf (FILE *fp, const wchar_t *format, ...)
{
va_list ap;
int done;
va_start (ap, format);
done = __vfwprintf_internal (fp, format, ap,
PRINTF_LDBL_USES_FLOAT128);
va_end (ap);
return done;
}
strong_alias (___ieee128_fwprintf, __fwprintfieee128)

View File

@ -0,0 +1,36 @@
/* Wrapper for swprintf. IEEE128 version.
Copyright (C) 2019 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
<http://www.gnu.org/licenses/>. */
#include <stdarg.h>
#include <libio/libioP.h>
extern int
___ieee128_swprintf (wchar_t *string, size_t maxlen,
const wchar_t *format, ...)
{
va_list ap;
int done;
va_start (ap, format);
done = __vswprintf_internal (string, maxlen, format, ap,
PRINTF_LDBL_USES_FLOAT128);
va_end (ap);
return done;
}
strong_alias (___ieee128_swprintf, __swprintfieee128)

View File

@ -0,0 +1,27 @@
/* Wrapper for vfwprintf. IEEE128 version.
Copyright (C) 2019 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
<http://www.gnu.org/licenses/>. */
#include <libio/libioP.h>
extern int
___ieee128_vfwprintf (FILE *fp, const wchar_t *format, va_list ap)
{
return __vfwprintf_internal (fp, format, ap,
PRINTF_LDBL_USES_FLOAT128);
}
strong_alias (___ieee128_vfwprintf, __vfwprintfieee128)

View File

@ -0,0 +1,28 @@
/* Wrapper for vswprintf. IEEE128 version.
Copyright (C) 2019 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
<http://www.gnu.org/licenses/>. */
#include <libio/libioP.h>
extern int
___ieee128_vswprintf (wchar_t *string, size_t maxlen,
const wchar_t *format, va_list ap)
{
return __vswprintf_internal (string, maxlen, format, ap,
PRINTF_LDBL_USES_FLOAT128);
}
strong_alias (___ieee128_vswprintf, __vswprintfieee128)

View File

@ -0,0 +1,27 @@
/* Wrapper for vwprintf. IEEE128 version.
Copyright (C) 2019 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
<http://www.gnu.org/licenses/>. */
#include <libio/libioP.h>
extern int
___ieee128_vwprintf (const wchar_t *format, va_list ap)
{
return __vfwprintf_internal (stdout, format, ap,
PRINTF_LDBL_USES_FLOAT128);
}
strong_alias (___ieee128_vwprintf, __vwprintfieee128)

View File

@ -0,0 +1,35 @@
/* Wrapper for wprintf. IEEE128 version.
Copyright (C) 2019 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
<http://www.gnu.org/licenses/>. */
#include <stdarg.h>
#include <libio/libioP.h>
extern int
___ieee128_wprintf (const wchar_t *format, ...)
{
va_list ap;
int done;
va_start (ap, format);
done = __vfwprintf_internal (stdout, format, ap,
PRINTF_LDBL_USES_FLOAT128);
va_end (ap);
return done;
}
strong_alias (___ieee128_wprintf, __wprintfieee128)

View File

@ -0,0 +1 @@
#include <test-wprintf-ldbl-compat.c>

View File

@ -0,0 +1 @@
#include <test-wprintf-ldbl-compat.c>

View File

@ -0,0 +1,111 @@
/* Test for the long double variants of *w*printf functions.
Copyright (C) 2019 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
<http://www.gnu.org/licenses/>. */
#include <stdarg.h>
#include <stdint.h>
#include <stdio.h>
#include <wchar.h>
#include <support/capture_subprocess.h>
#include <support/check.h>
static void
do_test_call_varg (FILE *stream, const wchar_t *format, ...)
{
wchar_t string[128];
va_list args;
wprintf (L"%15Ls", L"vfwprintf: ");
va_start (args, format);
vfwprintf (stream, format, args);
va_end (args);
wprintf (L"\n");
wprintf (L"%15Ls", L"vswprintf: ");
va_start (args, format);
vswprintf (string, 127, format, args);
va_end (args);
wprintf (L"%Ls", string);
wprintf (L"\n");
wprintf (L"%15Ls", L"vwprintf: ");
va_start (args, format);
vwprintf (format, args);
va_end (args);
wprintf (L"\n");
}
static void
do_test_call_rarg (FILE *stream, const wchar_t *format, long double ld)
{
wchar_t string[128];
wprintf (L"%15Ls", L"fwprintf: ");
fwprintf (stream, format, ld);
wprintf (L"\n");
wprintf (L"%15Ls", L"swprintf: ");
swprintf (string, 127, format, ld);
wprintf (L"%Ls", string);
wprintf (L"\n");
wprintf (L"%15Ls", L"wprintf: ");
wprintf (format, ld);
wprintf (L"\n");
}
static void
do_test_call (void)
{
long double ld = -1;
/* Print in decimal notation. */
do_test_call_rarg (stdout, L"%.10Lf", ld);
do_test_call_varg (stdout, L"%.10Lf", ld);
/* Print in hexadecimal notation. */
do_test_call_rarg (stdout, L"%.10La", ld);
do_test_call_varg (stdout, L"%.10La", ld);
}
static int
do_test (void)
{
struct support_capture_subprocess result;
result = support_capture_subprocess ((void *) &do_test_call, NULL);
/* Compare against the expected output. */
const char *expected =
" fwprintf: -1.0000000000\n"
" swprintf: -1.0000000000\n"
" wprintf: -1.0000000000\n"
" vfwprintf: -1.0000000000\n"
" vswprintf: -1.0000000000\n"
" vwprintf: -1.0000000000\n"
" fwprintf: -0x1.0000000000p+0\n"
" swprintf: -0x1.0000000000p+0\n"
" wprintf: -0x1.0000000000p+0\n"
" vfwprintf: -0x1.0000000000p+0\n"
" vswprintf: -0x1.0000000000p+0\n"
" vwprintf: -0x1.0000000000p+0\n";
TEST_COMPARE_STRING (expected, result.out.buffer);
return 0;
}
#include <support/test-driver.c>