about summary refs log tree commit diff
diff options
context:
space:
mode:
authorUlrich Drepper <drepper@redhat.com>2005-04-27 04:33:01 +0000
committerUlrich Drepper <drepper@redhat.com>2005-04-27 04:33:01 +0000
commit935f3e6715f2f178159eef1501ae30ad53a68150 (patch)
treef484c7c6c87c97774f3840c051804e42aa3588c0
parentbfc832ccf15e467b6271e8b237e467a30efd3d12 (diff)
downloadglibc-935f3e6715f2f178159eef1501ae30ad53a68150.tar.gz
glibc-935f3e6715f2f178159eef1501ae30ad53a68150.tar.xz
glibc-935f3e6715f2f178159eef1501ae30ad53a68150.zip
* time/strptime_l.c (__strptime_internal): Handle 'z' to set
	tm_gmtoff.
	* time/Makefile (tests): Add tst-strptime2.
	* time/tst-strptime2.c: New file.
-rw-r--r--ChangeLog7
-rw-r--r--localedata/ChangeLog6
-rw-r--r--localedata/locales/fa_IR211
-rw-r--r--time/Makefile4
-rw-r--r--time/strptime_l.c36
-rw-r--r--time/tst-strptime2.c59
6 files changed, 264 insertions, 59 deletions
diff --git a/ChangeLog b/ChangeLog
index 20628040da..bd82464850 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2005-04-26  Ulrich Drepper  <drepper@redhat.com>
+
+	* 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  <jakub@redhat.com>
 
 	* 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  <drepper@redhat.com>
+
+	* locales/fa_IR: Add alt_digits, change date and time
+	representation, and various cleanups.
+	Patch by Hamed Malek <hamed@bamdad.org>.
+
 2005-03-21  Jakub Jelinek  <jakub@redhat.com>
 
 	[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 <U06F0>..<U06F9>
 
+% This is used in the scanf family of functions to read Persian numbers
+% using "%Id" and such.
 map to_inpunct; /
   (<U0030>,<U06F0>); /
   (<U0031>,<U06F1>); /
@@ -64,6 +67,8 @@ map to_inpunct; /
   (<U002E>,<U066B>); /
   (<U002C>,<U066C>)
 
+% This is used in the printf family of functions to write Persian floating
+% point numbers using "%If" and such.
 map to_outpunct; /
   (<U002E>,<U066B>); /
   (<U002C>,<U066C>)
@@ -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 <AHY> % accent hamza over yeh
@@ -122,7 +127,7 @@ reorder-after <waw>
 <heh>
 <yeh>
 
-% Persian uses fatha, kasra, damma, fathatan, kasratan, dammatan order.
+% Persian uses this order: Fatha, Kasra, Damma, Fathatan, Kasratan, Dammatan.
 
 reorder-after <U066D>
 <U064E> IGNORE;IGNORE;IGNORE;<U064E> %<fatha_no>
@@ -148,7 +153,7 @@ reorder-after <UFE7F>
 <U0655> IGNORE;IGNORE;IGNORE;<U0655> %<hamzabelow_no>
 <U0670> IGNORE;IGNORE;IGNORE;<U0670> %<supalef_no>
 
-% 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 <U0660>
 <U06F0> <0>;<BAS>;<MIN>;IGNORE
 <U0660> <0>;<PCL>;<MIN>;IGNORE
@@ -292,14 +297,72 @@ grouping          3
 END LC_NUMERIC
 
 LC_TIME
-abday   "<U06CC><U002E>";"<U062F><U002E>";"<U0633><U002E>";/
-        "<U0686><U002E>";"<U067E><U002E>";"<U062C><U002E>";/
-        "<U0634><U002E>"
-day     "<U06CC><U06A9><U200C><U0634><U0646><U0628><U0647>";/
+% 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	"<U06F0><U06F0>";"<U06F0><U06F1>";/
+		"<U06F0><U06F2>";"<U06F0><U06F3>";/
+		"<U06F0><U06F4>";"<U06F0><U06F5>";/
+		"<U06F0><U06F6>";"<U06F0><U06F7>";/
+		"<U06F0><U06F8>";"<U06F0><U06F9>";/
+		"<U06F1><U06F0>";"<U06F1><U06F1>";/
+		"<U06F1><U06F2>";"<U06F1><U06F3>";/
+		"<U06F1><U06F4>";"<U06F1><U06F5>";/
+		"<U06F1><U06F6>";"<U06F1><U06F7>";/
+		"<U06F1><U06F8>";"<U06F1><U06F9>";/
+		"<U06F2><U06F0>";"<U06F2><U06F1>";/
+		"<U06F2><U06F2>";"<U06F2><U06F3>";/
+		"<U06F2><U06F4>";"<U06F2><U06F5>";/
+		"<U06F2><U06F6>";"<U06F2><U06F7>";/
+		"<U06F2><U06F8>";"<U06F2><U06F9>";/
+		"<U06F3><U06F0>";"<U06F3><U06F1>";/
+		"<U06F3><U06F2>";"<U06F3><U06F3>";/
+		"<U06F3><U06F4>";"<U06F3><U06F5>";/
+		"<U06F3><U06F6>";"<U06F3><U06F7>";/
+		"<U06F3><U06F8>";"<U06F3><U06F9>";/
+		"<U06F4><U06F0>";"<U06F4><U06F1>";/
+		"<U06F4><U06F2>";"<U06F4><U06F3>";/
+		"<U06F4><U06F4>";"<U06F4><U06F5>";/
+		"<U06F4><U06F6>";"<U06F4><U06F7>";/
+		"<U06F4><U06F8>";"<U06F4><U06F9>";/
+		"<U06F5><U06F0>";"<U06F5><U06F1>";/
+		"<U06F5><U06F2>";"<U06F5><U06F3>";/
+		"<U06F5><U06F4>";"<U06F5><U06F5>";/
+		"<U06F5><U06F6>";"<U06F5><U06F7>";/
+		"<U06F5><U06F8>";"<U06F5><U06F9>";/
+		"<U06F6><U06F0>";"<U06F6><U06F1>";/
+		"<U06F6><U06F2>";"<U06F6><U06F3>";/
+		"<U06F6><U06F4>";"<U06F6><U06F5>";/
+		"<U06F6><U06F6>";"<U06F6><U06F7>";/
+		"<U06F6><U06F8>";"<U06F6><U06F9>";/
+		"<U06F7><U06F0>";"<U06F7><U06F1>";/
+		"<U06F7><U06F2>";"<U06F7><U06F3>";/
+		"<U06F7><U06F4>";"<U06F7><U06F5>";/
+		"<U06F7><U06F6>";"<U06F7><U06F7>";/
+		"<U06F7><U06F8>";"<U06F7><U06F9>";/
+		"<U06F8><U06F0>";"<U06F8><U06F1>";/
+		"<U06F8><U06F2>";"<U06F8><U06F3>";/
+		"<U06F8><U06F4>";"<U06F8><U06F5>";/
+		"<U06F8><U06F6>";"<U06F8><U06F7>";/
+		"<U06F8><U06F8>";"<U06F8><U06F9>";/
+		"<U06F9><U06F0>";"<U06F9><U06F1>";/
+		"<U06F9><U06F2>";"<U06F9><U06F3>";/
+		"<U06F9><U06F4>";"<U06F9><U06F5>";/
+		"<U06F9><U06F6>";"<U06F9><U06F7>";/
+		"<U06F9><U06F8>";"<U06F9><U06F9>"
+% 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   "<U06CC><U06A9><U0634><U0646><U0628><U0647>";/
         "<U062F><U0648><U0634><U0646><U0628><U0647>";/
         "<U0633><U0647><U200C><U0634><U0646><U0628><U0647>";/
         "<U0686><U0647><U0627><U0631><U0634><U0646><U0628><U0647>";/
-        "<U067E><U0646><U062C><U200C><U0634><U0646><U0628><U0647>";/
+        "<U067E><U0646><U062C><U0634><U0646><U0628><U0647>";/
+        "<U062C><U0645><U0639><U0647>";/
+        "<U0634><U0646><U0628><U0647>"
+day     "<U06CC><U06A9><U0634><U0646><U0628><U0647>";/
+        "<U062F><U0648><U0634><U0646><U0628><U0647>";/
+        "<U0633><U0647><U200C><U0634><U0646><U0628><U0647>";/
+        "<U0686><U0647><U0627><U0631><U0634><U0646><U0628><U0647>";/
+        "<U067E><U0646><U062C><U0634><U0646><U0628><U0647>";/
         "<U062C><U0645><U0639><U0647>";/
         "<U0634><U0646><U0628><U0647>"
 mon     "<U0698><U0627><U0646><U0648><U06CC><U0647>";/
@@ -314,33 +377,68 @@ mon     "<U0698><U0627><U0646><U0648><U06CC><U0647>";/
         "<U0627><U0643><U062A><U0628><U0631>";/
         "<U0646><U0648><U0627><U0645><U0628><U0631>";/
         "<U062F><U0633><U0627><U0645><U0628><U0631>"
-abmon   "<U0698><U0627><U0646>";"<U0641><U0648><U0631>";/
-        "<U0645><U0627><U0631>";"<U0622><U0648><U0631>";/
-        "<U0645><U0640><U0647>";"<U0698><U0648><U0646>";/
-        "<U0698><U0648><U06CC>";"<U0627><U0648><U062A>";/
-        "<U0633><U067E><U062A>";"<U0627><U0643><U062A>";/
-        "<U0646><U0648><U0627>";"<U062F><U0633><U0627>"
-am_pm   "<U0635><U0628><U062D>";"<U0639><U0635><U0631>"
-d_t_fmt "<U202B><U0025><U0041><U0020><U0025><U0065><U0020><U0025>/
-<U0042><U0020><U0025><U0059><U060C><U0020><U0025><U0049><U003A>/
-<U0025><U004D><U003A><U0025><U0053><U0020><U0025><U0070><U202C>"
-d_fmt   "<U0025><U0059><U002F><U0025><U006D><U002F><U0025><U0064>"
-t_fmt   "<U0025><U0048><U003A><U0025><U004D><U003A><U0025><U0053>"
-t_fmt_ampm    "<U202B><U0025><U0049><U003A><U0025><U004D><U003A><U0025>/
-<U0053><U0020><U0025><U0070><U202C>"
-%date_fmt "<U0025><U0061><U0020><U0025><U0062><U0020><U0025><U0065><U0020>/
-%<U0025><U0048><U003A><U0025><U004D><U003A><U0025><U0053><U0020><U0025>/
-%<U005A><U0020><U0025><U0059>"
+abmon   "<U0698><U0627><U0646><U0648><U06CC><U0647>";/
+        "<U0641><U0648><U0631><U06CC><U0647>";/
+        "<U0645><U0627><U0631><U0633>";/
+        "<U0622><U0648><U0631><U06CC><U0644>";/
+        "<U0645><U0647>";/
+        "<U0698><U0648><U0626><U0646>";/
+        "<U0698><U0648><U0626><U06CC><U0647>";/
+        "<U0627><U0648><U062A>";/
+        "<U0633><U067E><U062A><U0627><U0645><U0628><U0631>";/
+        "<U0627><U0643><U062A><U0628><U0631>";/
+        "<U0646><U0648><U0627><U0645><U0628><U0631>";/
+        "<U062F><U0633><U0627><U0645><U0628><U0631>"
+% Persian does not have the 12-hour format
+am_pm   "";""
+t_fmt_ampm    ""
+%
+% Appropriate date representation (%x)
+%       "%Oy/%Om/%Od"
+d_fmt   "<U0025><U004F><U0079><U002F>/
+<U0025><U004F><U006D><U002F>/
+<U0025><U004F><U0064>"
+%
+% Appropriate time representation (%X)
+%       "%OH:%OM:%OS"
+t_fmt   "<U0025><U004F><U0048><U003A>/
+<U0025><U004F><U004D><U003A>/
+<U0025><U004F><U0053>"
+%
+% FIXME: need to add "HAMZA ABOVE" after January, February, May, July when used
+% before a year
+%
+% Appropriate date and time representation (%c)
+%       "<RLE>%A %Oe %B %Oy<ARABIC COMMA> %OH:%OM:%OS<PDF>"
+d_t_fmt "<U202B><U0025><U0041><U0020>/
+<U0025><U004F><U0065><U0020>/
+<U0025><U0042><U0020>/
+<U0025><U004F><U0079><U060C><U0020>/
+<U0025><U004F><U0048><U003A>/
+<U0025><U004F><U004D><U003A>/
+<U0025><U004F><U0053><U202C>"
+%
+% Appropriate date representation (date(1))
+%       "<RLE>%A %Oe %B %Oy<ARABIC COMMA> <SEEN><ALEF><AIN><TEH> %OH:%OM:%OS (%Z)<PDF>"
+date_fmt "<U202B><U0025><U0041><U0020>/
+<U0025><U004F><U0065><U0020>/
+<U0025><U0042><U0020>/
+<U0025><U004F><U0079><U060C><U0020>/
+<U0633><U0627><U0639><U062A><U0020>/
+<U0025><U004F><U0048><U003A>/
+<U0025><U004F><U004D><U003A>/
+<U0025><U004F><U0053><U0020>/
+<U0028><U0025><U005A><U0029><U202C>"
 first_weekday 7
 first_workday 7
 cal_direction 3
-%week    7;19971206;4
-%time_zone "???"
 END LC_TIME
 
 LC_MESSAGES
-yesexpr "<U005E><U005B><U0079><U0059><U0628><U0066><U005D><U002E><U002A>"
-noexpr  "<U005E><U005B><U006E><U004E><U062E><U0646><U006F><U005D><U002E><U002A>"
+% This is "^[yY<ALEF MADDA><BEH>Hf].*"
+yesexpr "<U005E><U005B><U0079><U0059><U0622><U0628><U0048><U0066><U005D><U002E><U002A>"
+% This is "^[nN<KHAH><NOON>ok].*"
+noexpr  "<U005E><U005B><U006E><U004E><U062E><U0646><U006F><U006B><U005D><U002E><U002A>"
 END LC_MESSAGES
 
 LC_PAPER
@@ -348,18 +446,6 @@ height   297
 width    210
 END LC_PAPER
 
-LC_TELEPHONE
-tel_int_fmt    "<U202A><U002B><U0025><U0063><U0020><U0025><U0061><U0020>/
-<U0025><U006C><U202C>"
-tel_dom_fmt    "<U202A><U0025><U0041><U2012><U0025><U006C><U202C>"
-int_select     "<U0030><U0030>"
-int_prefix     "<U0039><U0038>"
-END LC_TELEPHONE
-
-LC_MEASUREMENT
-measurement    1
-END LC_MEASUREMENT
-
 LC_NAME
 name_gen    ""
 name_miss   "<U062E><U0627><U0646><U0645>"
@@ -371,7 +457,6 @@ name_fmt    "<U0025><U0064><U0025><U0074><U0025><U0073><U0025><U0074>/
 END LC_NAME
 
 LC_ADDRESS
-% FIXME
 postal_fmt    "<U0025><U0066><U0025><U004E><U0025><U0061><U0025><U004E>/
 <U0025><U0064><U0025><U004E><U0025><U0062><U0025><U004E><U0025><U0073>/
 <U0020><U0025><U0068><U0020><U0025><U0065><U0020><U0025><U0072><U0025>/
@@ -388,3 +473,15 @@ lang_ab        "<U0066><U0061>"
 lang_term      "<U0066><U0061><U0073>"
 lang_lib       "<U0070><U0065><U0072>"
 END LC_ADDRESS
+
+LC_TELEPHONE
+tel_int_fmt    "<U202A><U002B><U0025><U0063><U0020><U0025><U0061><U0020>/
+<U0025><U006C><U202C>"
+tel_dom_fmt    "<U202A><U0025><U0041><U2012><U0025><U006C><U202C>"
+int_select     "<U0030><U0030>"
+int_prefix     "<U0039><U0038>"
+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 <limits.h>
+#include <stdio.h>
+#include <time.h>
+
+
+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;
+}