bug-gnulib
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [PATCH] "date" malfunctions in the Turkish locale


From: Jim Meyering
Subject: Re: [PATCH] "date" malfunctions in the Turkish locale
Date: Sat, 02 Aug 2008 15:56:23 +0200

Vefa Bicakci <address@hidden> wrote:
> As you can guess from the subject line, the date program

Thank you for the bug report!
To summarize, this invocation of date should not fail:

    $ LC_MESSAGES=C LC_CTYPE=tr_TR.UTF-8 date -d Fri
    date: invalid date `Fri'
...
> +  setlocale(LC_ALL, "C");
>    /* Make it uppercase.  */
>    for (p = word; *p; p++)
>      {
>        unsigned char ch = *p;
>        *p = toupper (ch);
>      }
> +  setlocale(LC_ALL, "");

Thanks for the patch.
However, I can't use it for two reasons:
  - first, it doesn't necessarily restore the locale settings
    to pre-get_date state (though that could be fixed).

More importantly,
  - it changes process-global state (albeit temporarily), which is
    better avoided in multi-threaded applications.

Here's a proposed patch to solve the problem without changing locale.
Since tables are all ASCII, we can simply use c_toupper instead
of toupper.  While not necessary, I've gone ahead and changed to
c_isspace and c_isalpha as well.  Any application that relies on getdate
skipping leading white space characters not in the ASCII set already has
locale-dependent bugs.  In other words, while this change does restrict
the input grammar slightly, it is for a good cause: making the grammar
locale-independent.

Barring objections, I'll push this on Monday.

>From cfd6d6448c3e1f1fec7f50ad1b58d252d172eec8 Mon Sep 17 00:00:00 2001
From: Jim Meyering <address@hidden>
Date: Sat, 2 Aug 2008 15:40:39 +0200
Subject: [PATCH] getdate.y: avoid locale-dependent date parsing failure

In Turkish locales, getdate would fail to recognize keywords
containing a lowercase "i".  The solution is not to rely on
locale-sensitive case-conversion.
* lib/getdate.y: Include <c-ctype.h> rather than <ctype.h>.
(lookup_word): Use c_toupper in place of toupper.
(yylex, get_date): Use c_ prefixed variants of isspace and isalpha, too.
Reported by Vefa Bicakci <address@hidden> in
<http://thread.gmane.org/gmane.comp.gnu.coreutils.bugs/14184>.
---
 ChangeLog     |   12 ++++++++++++
 lib/getdate.y |   14 +++++++-------
 2 files changed, 19 insertions(+), 7 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index e5bbf45..03328e0 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,15 @@
+2008-08-02  Jim Meyering  <address@hidden>
+
+       getdate.y: avoid locale-dependent date parsing failure
+       In Turkish locales, getdate would fail to recognize keywords
+       containing a lowercase "i".  The solution is not to rely on
+       locale-sensitive case-conversion.
+       * lib/getdate.y: Include <c-ctype.h> rather than <ctype.h>.
+       (lookup_word): Use c_toupper in place of toupper.
+       (yylex, get_date): Use c_ prefixed variants of isspace and isalpha, too.
+       Reported by Vefa Bicakci <address@hidden> in
+       <http://thread.gmane.org/gmane.comp.gnu.coreutils.bugs/14184>.
+
 2008-08-02  Ralf Wildenhues  <address@hidden>

        Portability fix for GNU make 3.79.1.
diff --git a/lib/getdate.y b/lib/getdate.y
index 695fd59..a94bf8b 100644
--- a/lib/getdate.y
+++ b/lib/getdate.y
@@ -60,7 +60,7 @@
 # undef static
 #endif

-#include <ctype.h>
+#include <c-ctype.h>
 #include <limits.h>
 #include <stdio.h>
 #include <stdlib.h>
@@ -900,7 +900,7 @@ lookup_word (parser_control const *pc, char *word)
   for (p = word; *p; p++)
     {
       unsigned char ch = *p;
-      *p = toupper (ch);
+      *p = c_toupper (ch);
     }

   for (tp = meridian_table; tp->name; tp++)
@@ -965,7 +965,7 @@ yylex (YYSTYPE *lvalp, parser_control *pc)

   for (;;)
     {
-      while (c = *pc->input, isspace (c))
+      while (c = *pc->input, c_isspace (c))
        pc->input++;

       if (ISDIGIT (c) || c == '-' || c == '+')
@@ -976,7 +976,7 @@ yylex (YYSTYPE *lvalp, parser_control *pc)
          if (c == '-' || c == '+')
            {
              sign = c == '-' ? -1 : 1;
-             while (c = *++pc->input, isspace (c))
+             while (c = *++pc->input, c_isspace (c))
                continue;
              if (! ISDIGIT (c))
                /* skip the '-' sign */
@@ -1080,7 +1080,7 @@ yylex (YYSTYPE *lvalp, parser_control *pc)
            }
        }

-      if (isalpha (c))
+      if (c_isalpha (c))
        {
          char buff[20];
          char *p = buff;
@@ -1092,7 +1092,7 @@ yylex (YYSTYPE *lvalp, parser_control *pc)
                *p++ = c;
              c = *++pc->input;
            }
-         while (isalpha (c) || c == '.');
+         while (c_isalpha (c) || c == '.');

          *p = '\0';
          tp = lookup_word (pc, buff);
@@ -1205,7 +1205,7 @@ get_date (struct timespec *result, char const *p, struct 
timespec const *now)
   if (! tmp)
     return false;

-  while (c = *p, isspace (c))
+  while (c = *p, c_isspace (c))
     p++;

   if (strncmp (p, "TZ=\"", 4) == 0)
--
1.6.0.rc1.36.g5ff70




reply via email to

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