Vefa Bicakci <[EMAIL PROTECTED]> 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 <[EMAIL PROTECTED]> 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 <[EMAIL PROTECTED]> 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 <[EMAIL PROTECTED]> + + 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 <[EMAIL PROTECTED]> in + <http://thread.gmane.org/gmane.comp.gnu.coreutils.bugs/14184>. + 2008-08-02 Ralf Wildenhues <[EMAIL PROTECTED]> 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