summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorvlefevre <vlefevre@280ebfd0-de03-0410-8827-d642c229c3f4>2018-07-30 13:43:03 +0000
committervlefevre <vlefevre@280ebfd0-de03-0410-8827-d642c229c3f4>2018-07-30 13:43:03 +0000
commit61419a00613066a02ee1dee8649e12dcc2f62466 (patch)
treef4e707540f132693b0a1793a8d38a4464c59c85e
parent461b550532a825c64e1eb4a9854f616f117512c3 (diff)
downloadmpfr-61419a00613066a02ee1dee8649e12dcc2f62466.tar.gz
[acinclude.m4,configure.ac] Check the support of the group flag for
native integers, which is a Single UNIX Specification extension. [src/vasprintf.c] Fixed bug with the P length modifier (mpfr_prec_t). [tests/tsprintf.c] Added testcases. (merged changesets r12958-12959,12961-12964 from the trunk) git-svn-id: svn://scm.gforge.inria.fr/svn/mpfr/branches/4.0@12967 280ebfd0-de03-0410-8827-d642c229c3f4
-rw-r--r--acinclude.m425
-rw-r--r--configure.ac3
-rw-r--r--src/vasprintf.c20
-rw-r--r--tests/tsprintf.c20
4 files changed, 58 insertions, 10 deletions
diff --git a/acinclude.m4 b/acinclude.m4
index 1c17223ae..88ed99c62 100644
--- a/acinclude.m4
+++ b/acinclude.m4
@@ -1433,6 +1433,31 @@ MPFR_FUNC_GMP_PRINTF_SPEC([td], [ptrdiff_t], [
[AC_DEFINE([NPRINTF_T], 1, [gmp_printf cannot read ptrdiff_t])])
])
+dnl MPFR_CHECK_PRINTF_GROUPFLAG
+dnl ---------------------------
+dnl Check the support of the group flag for native integers, which is
+dnl a Single UNIX Specification extension.
+dnl This will be used to enable some tests, as the implementation of
+dnl the P length modifier for mpfr_*printf relies on this support.
+
+AC_DEFUN([MPFR_CHECK_PRINTF_GROUPFLAG], [
+AC_MSG_CHECKING(if gmp_printf supports the ' group flag)
+AC_RUN_IFELSE([AC_LANG_PROGRAM([[
+#include <string.h>
+#include <gmp.h>
+]], [[
+ char s[256];
+
+ if (gmp_sprintf (s, "%'d", 17) == -1) return 1;
+ return (strcmp (s, "17") != 0);
+]])],
+ [AC_MSG_RESULT(yes)
+ AC_DEFINE([PRINTF_GROUPFLAG], 1, [Define if gmp_printf supports the ' group flag])],
+ [AC_MSG_RESULT(no)],
+ [AC_MSG_RESULT(cannot test, assume no)])
+])
+])
+
dnl MPFR_LTO
dnl --------
dnl To be representative, we need:
diff --git a/configure.ac b/configure.ac
index bea5aed06..80a183544 100644
--- a/configure.ac
+++ b/configure.ac
@@ -708,7 +708,8 @@ if test -z "$enable_mini_gmp" ; then
[AC_MSG_RESULT(yes)
MPFR_CHECK_GMP
MPFR_CHECK_DBL2INT_BUG
- MPFR_CHECK_PRINTF_SPEC],
+ MPFR_CHECK_PRINTF_SPEC
+ MPFR_CHECK_PRINTF_GROUPFLAG],
[AC_MSG_RESULT(no)
AC_MSG_WARN([==========================================================])
AC_MSG_WARN(['gmp.h' and 'libgmp' seem to have different versions or])
diff --git a/src/vasprintf.c b/src/vasprintf.c
index 99c8780b7..09df8c942 100644
--- a/src/vasprintf.c
+++ b/src/vasprintf.c
@@ -259,6 +259,8 @@ specinfo_is_valid (struct printf_spec spec)
}
}
+/* Note: additional flags should be added to the MPFR_PREC_ARG code
+ for gmp_asprintf (when supported). */
static const char *
parse_flags (const char *format, struct printf_spec *specinfo)
{
@@ -2220,7 +2222,7 @@ mpfr_vasnprintf_aux (char **ptr, char *Buf, size_t size, const char *fmt,
/* output mpfr_prec_t variable */
{
char *s;
- char format[MPFR_PREC_FORMAT_SIZE + 6]; /* see examples below */
+ char format[MPFR_PREC_FORMAT_SIZE + 12]; /* e.g. "%0#+ -'*.*ld\0" */
size_t length;
mpfr_prec_t prec;
@@ -2232,14 +2234,14 @@ mpfr_vasnprintf_aux (char **ptr, char *Buf, size_t size, const char *fmt,
start = fmt;
/* construct format string, like "%*.*hd" "%*.*d" or "%*.*ld" */
- format[0] = '%';
- format[1] = '*';
- format[2] = '.';
- format[3] = '*';
- format[4] = '\0';
- strcat (format, MPFR_PREC_FORMAT_TYPE);
- format[4 + MPFR_PREC_FORMAT_SIZE] = spec.spec;
- format[5 + MPFR_PREC_FORMAT_SIZE] = '\0';
+ sprintf (format, "%%%s%s%s%s%s%s*.*" MPFR_PREC_FORMAT_TYPE "%c",
+ spec.pad == '0' ? "0" : "",
+ spec.alt ? "#" : "",
+ spec.showsign ? "+" : "",
+ spec.space ? " " : "",
+ spec.left ? "-" : "",
+ spec.group ? "'" : "",
+ spec.spec);
length = gmp_asprintf (&s, format, spec.width, spec.prec, prec);
MPFR_ASSERTN (length >= 0); /* guaranteed by GMP 6 */
buffer_cat (&buf, s, length);
diff --git a/tests/tsprintf.c b/tests/tsprintf.c
index 21f298ec2..cf220c25c 100644
--- a/tests/tsprintf.c
+++ b/tests/tsprintf.c
@@ -232,6 +232,22 @@ decimal (void)
/* specifier 'P' for precision */
check_vsprintf ("128", "%Pu", p);
check_vsprintf ("00128", "%.5Pu", p);
+ check_vsprintf (" 128", "%5Pu", p);
+ check_vsprintf ("000128", "%06Pu", p);
+ check_vsprintf ("128 :", "%-7Pu:", p);
+ check_vsprintf ("000128:", "%-2.6Pd:", p);
+ check_vsprintf (" 000128:", "%8.6Pd:", p);
+ check_vsprintf ("000128 :", "%-8.6Pd:", p);
+ check_vsprintf ("+128:", "%+d:", p);
+ check_vsprintf (" 128:", "% d:", p);
+ check_vsprintf ("80:", "% x:", p);
+ check_vsprintf ("0x80:", "% #x:", p);
+ check_vsprintf ("0x80:", "%0#+ -x:", p);
+ check_vsprintf ("0200:", "%0#+ -o:", p);
+ check_vsprintf ("+0000128 :", "%0+ *.*Pd:", -9, 7, p);
+ check_vsprintf ("+12345 :", "%0+ -*.*Pd:", -9, -3, (mpfr_prec_t) 12345);
+ /* Do not add a test like "%05.1Pd" as MS Windows is buggy: when
+ a precision is given, the '0' flag must be ignored. */
/* special numbers */
mpfr_set_inf (x, 1);
@@ -1545,6 +1561,10 @@ test_locale (void)
check_sprintf ("00000001,000", "%'012.4Rg", x);
check_sprintf ("000000001,000", "%'013.4Rg", x);
+#ifdef PRINTF_GROUPFLAG
+ check_vsprintf ("+01,234,567 :", "%0+ -'13.10Pd:", (mpfr_prec_t) 1234567);
+#endif
+
mpfr_clear (x);
}