# HG changeset patch # User Bruno Haible # Date 1289152219 -3600 # Node ID 05717fb89fa47fb64f26475387ba72bb3850d4cb # Parent 4a556ba5903b518b75b5d4da1ef58962b3d25ae7 vasnprintf: Support I flag on glibc systems. * lib/printf-parse.h (FLAG_LOCALIZED): New macro. * lib/printf-parse.c (PRINTF_PARSE): Handle the 'I' flag. * lib/vasnprintf.c (VASNPRINTF): Pass the 'I' flag on to the system's snprintf function. * tests/test-vasnprintf-posix.c (test_function): Test the 'I' flag on glibc systems. * tests/test-vasnprintf-posix3.c: New file. * modules/vasnprintf-posix-tests (Files): Add it. (TESTS, check_PROGRAMS): Add test-vasnprintf-posix3. diff --git a/ChangeLog b/ChangeLog --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,16 @@ +2010-11-07 Bruno Haible + + vasnprintf: Support I flag on glibc systems. + * lib/printf-parse.h (FLAG_LOCALIZED): New macro. + * lib/printf-parse.c (PRINTF_PARSE): Handle the 'I' flag. + * lib/vasnprintf.c (VASNPRINTF): Pass the 'I' flag on to the system's + snprintf function. + * tests/test-vasnprintf-posix.c (test_function): Test the 'I' flag on + glibc systems. + * tests/test-vasnprintf-posix3.c: New file. + * modules/vasnprintf-posix-tests (Files): Add it. + (TESTS, check_PROGRAMS): Add test-vasnprintf-posix3. + 2010-11-05 Thien-Thi Nguyen (tiny change) [html] Fix copy/paste bug: Use unique name for compiler warnings. diff --git a/lib/printf-parse.c b/lib/printf-parse.c --- a/lib/printf-parse.c +++ b/lib/printf-parse.c @@ -206,6 +206,13 @@ dp->flags |= FLAG_ZERO; cp++; } +#if __GLIBC__ >= 2 + else if (*cp == 'I') + { + dp->flags |= FLAG_LOCALIZED; + cp++; + } +#endif else break; } diff --git a/lib/printf-parse.h b/lib/printf-parse.h --- a/lib/printf-parse.h +++ b/lib/printf-parse.h @@ -33,6 +33,9 @@ #define FLAG_SPACE 8 /* space flag */ #define FLAG_ALT 16 /* # flag */ #define FLAG_ZERO 32 +#if __GLIBC__ >= 2 +# define FLAG_LOCALIZED 64 /* I flag, uses localized digits */ +#endif /* arg_index value indicating that no argument is consumed. */ #define ARG_NONE (~(size_t)0) diff --git a/lib/vasnprintf.c b/lib/vasnprintf.c --- a/lib/vasnprintf.c +++ b/lib/vasnprintf.c @@ -4754,6 +4754,10 @@ *fbp++ = ' '; if (flags & FLAG_ALT) *fbp++ = '#'; +#if __GLIBC__ >= 2 + if (flags & FLAG_LOCALIZED) + *fbp++ = 'I'; +#endif if (!pad_ourselves) { if (flags & FLAG_ZERO) diff --git a/modules/vasnprintf-posix-tests b/modules/vasnprintf-posix-tests --- a/modules/vasnprintf-posix-tests +++ b/modules/vasnprintf-posix-tests @@ -2,6 +2,7 @@ tests/test-vasnprintf-posix.c tests/test-vasnprintf-posix2.sh tests/test-vasnprintf-posix2.c +tests/test-vasnprintf-posix3.c tests/minus-zero.h tests/nan.h tests/macros.h @@ -17,6 +18,6 @@ gt_LOCALE_FR_UTF8 Makefile.am: -TESTS += test-vasnprintf-posix test-vasnprintf-posix2.sh +TESTS += test-vasnprintf-posix test-vasnprintf-posix2.sh test-vasnprintf-posix3 TESTS_ENVIRONMENT += LOCALE_FR='@LOCALE_FR@' LOCALE_FR_UTF8='@LOCALE_FR_UTF8@' -check_PROGRAMS += test-vasnprintf-posix test-vasnprintf-posix2 +check_PROGRAMS += test-vasnprintf-posix test-vasnprintf-posix2 test-vasnprintf-posix3 diff --git a/tests/test-vasnprintf-posix.c b/tests/test-vasnprintf-posix.c --- a/tests/test-vasnprintf-posix.c +++ b/tests/test-vasnprintf-posix.c @@ -3658,6 +3658,19 @@ free (result); } #endif + +#if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 2) + /* Test that the 'I' flag is supported. */ + { + size_t length; + char *result = + my_asnprintf (NULL, &length, "%Id %d", 1234567, 99); + ASSERT (result != NULL); + ASSERT (strcmp (result, "1234567 99") == 0); + ASSERT (length == strlen (result)); + free (result); + } +#endif } static char * diff --git a/tests/test-vasnprintf-posix3.c b/tests/test-vasnprintf-posix3.c new file mode 100644 --- /dev/null +++ b/tests/test-vasnprintf-posix3.c @@ -0,0 +1,94 @@ +/* Test of POSIX compatible vasnprintf() and asnprintf() functions. + Copyright (C) 2010 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 , 2010. */ + +#include + +#include "vasnprintf.h" + +#include +#include +#include + +#include "macros.h" + +static void +test_function (char * (*my_asnprintf) (char *, size_t *, const char *, ...)) +{ + /* glibc >= 2.2 supports the 'I' flag, and in glibc >= 2.2.3 the fa_IR + locale defines the 'outdigits' to be U+06F0..U+06F9. + So we test for glibc >= 2.3. */ +#if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 3) + /* Test that the 'I' flag is supported. */ + { + size_t length; + char *result = + my_asnprintf (NULL, &length, "%Id %d", 1234567, 99); + static const char expected[] = /* "۱۲۳۴۵۶۷ 99" */ + "\xDB\xB1\xDB\xB2\xDB\xB3\xDB\xB4\xDB\xB5\xDB\xB6\xDB\xB7 99"; + ASSERT (result != NULL); + ASSERT (strcmp (result, expected) == 0); + ASSERT (length == strlen (result)); + free (result); + } +#endif +} + +static char * +my_asnprintf (char *resultbuf, size_t *lengthp, const char *format, ...) +{ + va_list args; + char *ret; + + va_start (args, format); + ret = vasnprintf (resultbuf, lengthp, format, args); + va_end (args); + return ret; +} + +static void +test_vasnprintf () +{ + test_function (my_asnprintf); +} + +static void +test_asnprintf () +{ + test_function (asnprintf); +} + +int +main (int argc, char *argv[]) +{ +#if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 3) + /* Select a locale with Arabic 'outdigits'. */ + if (setlocale (LC_ALL, "fa_IR.UTF-8") == NULL) + { + fprintf (stderr, "Skipping test: no Iranian locale is installed\n"); + return 77; + } + + test_vasnprintf (); + test_asnprintf (); + + return 0; +#else + fprintf (stderr, "Skipping test: not a glibc >= 2.3 system\n"); + return 77; +#endif +}