[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
vasnprintf: support glibc 'I' flag
From: |
Bruno Haible |
Subject: |
vasnprintf: support glibc 'I' flag |
Date: |
Sun, 7 Nov 2010 18:54:47 +0100 |
User-agent: |
KMail/1.9.9 |
Hi,
Just noticed that gnulib's vasnprintf function does not support the same flags
as the underlying system. In particular, glibc's 'I' flag (that causes
localized digits to appear in the output instead of ASCII digits - a feature
used in Farsi and Indic languages) ought to be supported by vasnprintf.
This fixes it.
2010-11-07 Bruno Haible <address@hidden>
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.
--- lib/printf-parse.c.orig Sun Nov 7 18:50:15 2010
+++ lib/printf-parse.c Sun Nov 7 17:39:27 2010
@@ -206,6 +206,13 @@
dp->flags |= FLAG_ZERO;
cp++;
}
+#if __GLIBC__ >= 2
+ else if (*cp == 'I')
+ {
+ dp->flags |= FLAG_LOCALIZED;
+ cp++;
+ }
+#endif
else
break;
}
--- lib/printf-parse.h.orig Sun Nov 7 18:50:15 2010
+++ lib/printf-parse.h Sun Nov 7 18:48:45 2010
@@ -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)
--- lib/vasnprintf.c.orig Sun Nov 7 18:50:15 2010
+++ lib/vasnprintf.c Sun Nov 7 17:45:20 2010
@@ -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)
--- modules/vasnprintf-posix-tests.orig Sun Nov 7 18:50:15 2010
+++ modules/vasnprintf-posix-tests Sun Nov 7 18:13:12 2010
@@ -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
--- tests/test-vasnprintf-posix.c.orig Sun Nov 7 18:50:15 2010
+++ tests/test-vasnprintf-posix.c Sun Nov 7 18:47:52 2010
@@ -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 *
======================= tests/test-vasnprintf-posix3.c =======================
/* 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 <http://www.gnu.org/licenses/>. */
/* Written by Bruno Haible <address@hidden>, 2010. */
#include <config.h>
#include "vasnprintf.h"
#include <locale.h>
#include <stdlib.h>
#include <string.h>
#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
}
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- vasnprintf: support glibc 'I' flag,
Bruno Haible <=