diff --git a/ChangeLog b/ChangeLog index 20628040da..bd82464850 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2005-04-26 Ulrich Drepper + + * time/strptime_l.c (__strptime_internal): Handle 'z' to set + tm_gmtoff. + * time/Makefile (tests): Add tst-strptime2. + * time/tst-strptime2.c: New file. + 2005-04-26 Jakub Jelinek * elf/dl-close.c: Include stddef.h. diff --git a/localedata/ChangeLog b/localedata/ChangeLog index a1d2a27b01..b0829cd181 100644 --- a/localedata/ChangeLog +++ b/localedata/ChangeLog @@ -1,3 +1,9 @@ +2005-04-26 Ulrich Drepper + + * locales/fa_IR: Add alt_digits, change date and time + representation, and various cleanups. + Patch by Hamed Malek . + 2005-03-21 Jakub Jelinek [BZ #823] diff --git a/localedata/locales/fa_IR b/localedata/locales/fa_IR index 8f65b1edd8..15fb535640 100644 --- a/localedata/locales/fa_IR +++ b/localedata/locales/fa_IR @@ -10,8 +10,8 @@ escape_char / % Fax: +98 21 6019568 % Language: fa % Territory: IR -% Revision: 2.4 -% Date: 2004-09-04 +% Revision: 3.0 +% Date: 2005-04-06 % Users: general % Repertoiremap: % Charset: UTF-8 @@ -28,28 +28,31 @@ tel "+98 21 6022372" fax "+98 21 6019568" language "Persian" territory "Iran" -revision "2.3" -date "2004-03-16" +revision "3.0" +date "2005-04-06" % -category "fa_IR:2004";LC_IDENTIFICATION -category "fa_IR:2004";LC_CTYPE -category "fa_IR:2004";LC_COLLATE -category "fa_IR:2004";LC_TIME -category "fa_IR:2004";LC_NUMERIC -category "fa_IR:2004";LC_MONETARY -category "fa_IR:2004";LC_MESSAGES -category "fa_IR:2004";LC_PAPER -category "fa_IR:2004";LC_NAME -category "fa_IR:2004";LC_ADDRESS -category "fa_IR:2004";LC_TELEPHONE +category "fa_IR:2005";LC_IDENTIFICATION +category "fa_IR:2005";LC_CTYPE +category "fa_IR:2005";LC_COLLATE +category "fa_IR:2005";LC_TIME +category "fa_IR:2005";LC_NUMERIC +category "fa_IR:2005";LC_MONETARY +category "fa_IR:2005";LC_MESSAGES +category "fa_IR:2005";LC_PAPER +category "fa_IR:2005";LC_NAME +category "fa_IR:2005";LC_ADDRESS +category "fa_IR:2005";LC_TELEPHONE END LC_IDENTIFICATION LC_CTYPE copy "i18n" +% Persian uses the alternate digits U+06F0..U+06F9 outdigit .. +% This is used in the scanf family of functions to read Persian numbers +% using "%Id" and such. map to_inpunct; / (,); / (,); / @@ -64,6 +67,8 @@ map to_inpunct; / (,); / (,) +% This is used in the printf family of functions to write Persian floating +% point numbers using "%If" and such. map to_outpunct; / (,); / (,) @@ -76,7 +81,7 @@ copy "iso14651_t1" % kinds), BEH, PEH, TEH, JEEM, TCHEH, HAH, KHAH, DAL, THAL, REH, ZAIN, JEH, % SEEN, SHEEN, SAD, DAD, TAH, ZAH, AIN, GHAIN, FEH, QAF, KAF, GAF, LAM, % MEEM, NOON, WAW, HEH, YEH. -% The various kind of HAMZA are sorted as ALEF WITH HAMZA ABOVE, ALEF WITH +% The various kinds of HAMZA are sorted as ALEF WITH HAMZA ABOVE, ALEF WITH % HAMZA BELOW, WAW WITH HAMZA ABOVE, YEH WITH HAMZA ABOVE. collating-symbol % accent hamza over yeh @@ -122,7 +127,7 @@ reorder-after -% Persian uses fatha, kasra, damma, fathatan, kasratan, dammatan order. +% Persian uses this order: Fatha, Kasra, Damma, Fathatan, Kasratan, Dammatan. reorder-after IGNORE;IGNORE;IGNORE; % @@ -148,7 +153,7 @@ reorder-after IGNORE;IGNORE;IGNORE; % IGNORE;IGNORE;IGNORE; % -% Persian digits are sorted before Arabic ones: they are the basic forms. +% The Persian digits are sorted before the Arabic ones: they are the basic forms. reorder-after <0>;;;IGNORE <0>;;;IGNORE @@ -292,14 +297,72 @@ grouping 3 END LC_NUMERIC LC_TIME -abday "";"";"";/ - "";"";"";/ - "" -day "";/ +% Alternative digits are used for Persian numerals in date and time. This is +% a hack, until a new prefix is defined for alternative digits. +alt_digits "";"";/ + "";"";/ + "";"";/ + "";"";/ + "";"";/ + "";"";/ + "";"";/ + "";"";/ + "";"";/ + "";"";/ + "";"";/ + "";"";/ + "";"";/ + "";"";/ + "";"";/ + "";"";/ + "";"";/ + "";"";/ + "";"";/ + "";"";/ + "";"";/ + "";"";/ + "";"";/ + "";"";/ + "";"";/ + "";"";/ + "";"";/ + "";"";/ + "";"";/ + "";"";/ + "";"";/ + "";"";/ + "";"";/ + "";"";/ + "";"";/ + "";"";/ + "";"";/ + "";"";/ + "";"";/ + "";"";/ + "";"";/ + "";"";/ + "";"";/ + "";"";/ + "";"";/ + "";"";/ + "";"";/ + "";"";/ + "";"";/ + "";"" +% Persian doesn't have abbreviations for weekdays and month names, so +% "abday" is the same as "day" and "abmon" is the same as "mon" +abday "";/ "";/ "";/ "";/ - "";/ + "";/ + "";/ + "" +day "";/ + "";/ + "";/ + "";/ + "";/ "";/ "" mon "";/ @@ -314,33 +377,68 @@ mon "";/ "";/ "";/ "" -abmon "";"";/ - "";"";/ - "";"";/ - "";"";/ - "";"";/ - "";"" -am_pm "";"" -d_t_fmt "/ -/ -" -d_fmt "" -t_fmt "" -t_fmt_ampm "/ -" -%date_fmt "/ -%/ -%" +abmon "";/ + "";/ + "";/ + "";/ + "";/ + "";/ + "";/ + "";/ + "";/ + "";/ + "";/ + "" +% Persian does not have the 12-hour format +am_pm "";"" +t_fmt_ampm "" +% +% Appropriate date representation (%x) +% "%Oy/%Om/%Od" +d_fmt "/ +/ +" +% +% Appropriate time representation (%X) +% "%OH:%OM:%OS" +t_fmt "/ +/ +" +% +% FIXME: need to add "HAMZA ABOVE" after January, February, May, July when used +% before a year +% +% Appropriate date and time representation (%c) +% "%A %Oe %B %Oy %OH:%OM:%OS" +d_t_fmt "/ +/ +/ +/ +/ +/ +" +% +% Appropriate date representation (date(1)) +% "%A %Oe %B %Oy %OH:%OM:%OS (%Z)" +date_fmt "/ +/ +/ +/ +/ +/ +/ +/ +" first_weekday 7 first_workday 7 cal_direction 3 -%week 7;19971206;4 -%time_zone "???" END LC_TIME LC_MESSAGES -yesexpr "" -noexpr "" +% This is "^[yYHf].*" +yesexpr "" +% This is "^[nNok].*" +noexpr "" END LC_MESSAGES LC_PAPER @@ -348,18 +446,6 @@ height 297 width 210 END LC_PAPER -LC_TELEPHONE -tel_int_fmt "/ -" -tel_dom_fmt "" -int_select "" -int_prefix "" -END LC_TELEPHONE - -LC_MEASUREMENT -measurement 1 -END LC_MEASUREMENT - LC_NAME name_gen "" name_miss "" @@ -371,7 +457,6 @@ name_fmt "/ END LC_NAME LC_ADDRESS -% FIXME postal_fmt "/ / / @@ -388,3 +473,15 @@ lang_ab "" lang_term "" lang_lib "" END LC_ADDRESS + +LC_TELEPHONE +tel_int_fmt "/ +" +tel_dom_fmt "" +int_select "" +int_prefix "" +END LC_TELEPHONE + +LC_MEASUREMENT +measurement 1 +END LC_MEASUREMENT diff --git a/time/Makefile b/time/Makefile index 7acc964fdc..14313563eb 100644 --- a/time/Makefile +++ b/time/Makefile @@ -1,4 +1,4 @@ -# Copyright (C) 1991-2002,2003,2004 Free Software Foundation, Inc. +# Copyright (C) 1991-2003, 2004, 2005 Free Software Foundation, Inc. # This file is part of the GNU C Library. # The GNU C Library is free software; you can redistribute it and/or @@ -35,7 +35,7 @@ distribute := datemsk tests := test_time clocktest tst-posixtz tst-strptime tst_wcsftime \ tst-getdate tst-mktime tst-mktime2 tst-ftime_l tst-strftime \ - tst-mktime3 + tst-mktime3 tst-strptime2 include ../Rules diff --git a/time/strptime_l.c b/time/strptime_l.c index 01c4f8282a..dc0cc686fd 100644 --- a/time/strptime_l.c +++ b/time/strptime_l.c @@ -687,6 +687,42 @@ __strptime_internal (rp, fmt, tm, decided, era_cnt LOCALE_PARAM) case 'Z': /* XXX How to handle this? */ break; + case 'z': + /* We recognize two formats: if two digits are given, these + specify hours. If fours digits are used, minutes are + also specified. */ + { + val = 0; + while (*rp == ' ') + ++rp; + if (*rp != '+' && *rp != '-') + return NULL; + bool neg = *rp++ == '-'; + int n = 0; + while (n < 4 && *rp >= '0' && *rp <= '9') + { + val = val * 10 + *rp++ - '0'; + ++n; + } + if (n == 2) + val *= 100; + else if (n != 4) + /* Only two or four digits recognized. */ + return NULL; + else + { + /* We have to convert the minutes into decimal. */ + if (val % 100 >= 60) + return NULL; + val = (val / 100) * 100 + ((val % 100) * 50) / 30; + } + if (val > 1200) + return NULL; + tm->tm_gmtoff = (val * 3600) / 100; + if (neg) + tm->tm_gmtoff = -tm->tm_gmtoff; + } + break; case 'E': #ifdef _NL_CURRENT switch (*fmt++) diff --git a/time/tst-strptime2.c b/time/tst-strptime2.c new file mode 100644 index 0000000000..73552bb8f8 --- /dev/null +++ b/time/tst-strptime2.c @@ -0,0 +1,59 @@ +#include +#include +#include + + +static const struct +{ + const char *fmt; + long int gmtoff; +} tests[] = + { + { "1113472456 +1000", 36000 }, + { "1113472456 -1000", -36000 }, + { "1113472456 +10", 36000 }, + { "1113472456 -10", -36000 }, + { "1113472456 +1030", 37800 }, + { "1113472456 -1030", -37800 }, + { "1113472456 +0030", 1800 }, + { "1113472456 -0030", -1800 }, + { "1113472456 -1330", LONG_MAX }, + { "1113472456 +1330", LONG_MAX }, + { "1113472456 -1060", LONG_MAX }, + { "1113472456 +1060", LONG_MAX }, + { "1113472456 1030", LONG_MAX }, + }; +#define ntests (sizeof (tests) / sizeof (tests[0])) + + +int +main (void) +{ + int result = 0; + + for (int i = 0; i < ntests; ++i) + { + struct tm tm; + + if (strptime (tests[i].fmt, "%s %z", &tm) == NULL) + { + if (tests[i].gmtoff != LONG_MAX) + { + printf ("round %d: strptime unexpectedly failed\n", i); + result = 1; + } + continue; + } + + if (tm.tm_gmtoff != tests[i].gmtoff) + { + printf ("round %d: tm_gmtoff is %ld\n", i, (long int) tm.tm_gmtoff); + result = 1; + } + } + + if (result == 0) + puts ("all OK"); + + return 0; +}