bug-gnulib
[Top][All Lists]
Advanced

[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
}



reply via email to

[Prev in Thread] Current Thread [Next in Thread]