From 044b16f4e9ae773187f4fee8a9a0a54f9a51f13f Mon Sep 17 00:00:00 2001 From: Ulrich Drepper Date: Tue, 5 Aug 1997 23:36:21 +0000 Subject: update for 2.0.5pre1 --- time/Makefile | 2 +- time/africa | 18 ++++---- time/asctime.c | 8 +++- time/asia | 45 +++++++++---------- time/australasia | 8 +++- time/europe | 54 +++++++++++++--------- time/iso3166.tab | 5 +-- time/mktime.c | 50 +++++++++++---------- time/private.h | 4 +- time/scheck.c | 2 +- time/strftime.c | 72 ++++++++++++++++++++++-------- time/strptime.c | 5 ++- time/tzfile.c | 19 ++++---- time/tzset.c | 134 ++++++++++++++++++++++++++++++++++++------------------- time/zone.tab | 6 +-- 15 files changed, 267 insertions(+), 165 deletions(-) (limited to 'time') diff --git a/time/Makefile b/time/Makefile index 1d8490cc8b..ec870f2700 100644 --- a/time/Makefile +++ b/time/Makefile @@ -187,7 +187,7 @@ $(objpfx)testdata/UTC: simplebackw $(objpfx)zic $(objpfx)testdata/Etc/UTC \ test-tz-ENV = TZDIR=$(objpfx)testdata -$(objpfx)tzselect: tzselect.ksh +$(objpfx)tzselect: tzselect.ksh $(common-objpfx)config.make sed -e 's%@KSH@%$(KSH)%g' \ -e 's%@TZDIR@%$(zonedir)%g' < $< > $@.new chmod 555 $@.new diff --git a/time/africa b/time/africa index 1ac3835056..2ea89bd5e0 100644 --- a/time/africa +++ b/time/africa @@ -1,4 +1,4 @@ -# @(#)africa 7.17 +# @(#)africa 7.18 # This data is by no means authoritative; if you think you know better, # go ahead and edit the file (and please send any changes to @@ -218,7 +218,14 @@ Zone Africa/Ndjamena 1:00:12 - LMT 1912 Zone Indian/Comoro 2:53:04 - LMT 1911 Jul # Moroni, Gran Comoro 3:00 - EAT -# Congo +# Democratic Republic of Congo +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Africa/Kinshasa 1:01:12 - LMT 1897 Nov 9 + 1:00 - CAT +Zone Africa/Lubumbashi 1:49:52 - LMT 1897 Nov 9 + 2:00 - SAT + +# Republic of the Congo # Zone NAME GMTOFF RULES FORMAT [UNTIL] Zone Africa/Brazzaville 1:01:08 - LMT 1912 1:00 - CAT @@ -656,13 +663,6 @@ Zone Africa/Kampala 2:09:40 - LMT 1928 Jul 2:45 - BEAT 1957 3:00 - EAT -# Zaire -# Zone NAME GMTOFF RULES FORMAT [UNTIL] -Zone Africa/Kinshasa 1:01:12 - LMT 1897 Nov 9 - 1:00 - CAT -Zone Africa/Lubumbashi 1:49:52 - LMT 1897 Nov 9 - 2:00 - SAT - # Zambia # Zone NAME GMTOFF RULES FORMAT [UNTIL] Zone Africa/Lusaka 1:53:08 - LMT 1903 Mar diff --git a/time/asctime.c b/time/asctime.c index 82e9f72f3f..730c6dc12b 100644 --- a/time/asctime.c +++ b/time/asctime.c @@ -21,6 +21,10 @@ #include #include +/* This is defined in locale/C-time.c in the GNU libc. */ +extern const struct locale_data _nl_C_LC_TIME; +#define ab_day_name (&_nl_C_LC_TIME.values[_NL_ITEM_INDEX (ABDAY_1)].string) +#define ab_month_name (&_nl_C_LC_TIME.values[_NL_ITEM_INDEX (ABMON_1)].string) static const char format[] = "%.3s %.3s%3d %.2d:%.2d:%.2d %d\n"; static char result[ 3+1+ 3+1+20+1+20+1+20+1+20+1+20+1 + 1]; @@ -45,9 +49,9 @@ __asctime_r (const struct tm *tp, char *buf) if (sprintf (buf, format, (tp->tm_wday < 0 || tp->tm_wday >= 7 ? - "???" : _NL_CURRENT (LC_TIME, ABDAY_1 + tp->tm_wday)), + "???" : ab_day_name[tp->tm_wday]), (tp->tm_mon < 0 || tp->tm_mon >= 12 ? - "???" : _NL_CURRENT (LC_TIME, ABMON_1 + tp->tm_mon)), + "???" : ab_month_name[tp->tm_mon]), tp->tm_mday, tp->tm_hour, tp->tm_min, tp->tm_sec, 1900 + tp->tm_year) < 0) return NULL; diff --git a/time/asia b/time/asia index 829d40b9a8..6734749179 100644 --- a/time/asia +++ b/time/asia @@ -1,4 +1,4 @@ -# @(#)asia 7.29 +# @(#)asia 7.30 # This data is by no means authoritative; if you think you know better, # go ahead and edit the file (and please send any changes to @@ -214,28 +214,6 @@ Zone Asia/Kashgar 5:03:56 - LMT 1928 5:30 - KAST 1940 # Kashgar Time 5:00 - KAST 1980 May 8:00 PRC C%sT - -############################################################################### - -# Republic of China - -# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S -Rule Taiwan 1945 1951 - May 1 0:00 1:00 D -Rule Taiwan 1945 1951 - Oct 1 0:00 0 S -Rule Taiwan 1952 only - Mar 1 0:00 1:00 D -Rule Taiwan 1952 1954 - Nov 1 0:00 0 S -Rule Taiwan 1953 1959 - Apr 1 0:00 1:00 D -Rule Taiwan 1955 1961 - Oct 1 0:00 0 S -Rule Taiwan 1960 1961 - Jun 1 0:00 1:00 D -Rule Taiwan 1974 1975 - Apr 1 0:00 1:00 D -Rule Taiwan 1974 1975 - Oct 1 0:00 0 S -Rule Taiwan 1980 only - Jun 30 0:00 1:00 D -Rule Taiwan 1980 only - Sep 30 0:00 0 S -# Zone NAME GMTOFF RULES FORMAT [UNTIL] -Zone Asia/Taipei 8:06:00 - LMT 1896 - 8:00 Taiwan C%sT - -############################################################################### # Hong Kong # Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S Rule HK 1946 only - Apr 20 3:30 1:00 S @@ -258,6 +236,27 @@ Zone Asia/Hong_Kong 7:36:36 - LMT 1904 Oct 30 8:00 HK HK%sT 1997 Jul 1 # return to China 8:00 PRC C%sT + +############################################################################### + +# Republic of China + +# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S +Rule Taiwan 1945 1951 - May 1 0:00 1:00 D +Rule Taiwan 1945 1951 - Oct 1 0:00 0 S +Rule Taiwan 1952 only - Mar 1 0:00 1:00 D +Rule Taiwan 1952 1954 - Nov 1 0:00 0 S +Rule Taiwan 1953 1959 - Apr 1 0:00 1:00 D +Rule Taiwan 1955 1961 - Oct 1 0:00 0 S +Rule Taiwan 1960 1961 - Jun 1 0:00 1:00 D +Rule Taiwan 1974 1975 - Apr 1 0:00 1:00 D +Rule Taiwan 1974 1975 - Oct 1 0:00 0 S +Rule Taiwan 1980 only - Jun 30 0:00 1:00 D +Rule Taiwan 1980 only - Sep 30 0:00 0 S +# Zone NAME GMTOFF RULES FORMAT [UNTIL] +Zone Asia/Taipei 8:06:00 - LMT 1896 + 8:00 Taiwan C%sT + # Macao # Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S Rule Macao 1961 1962 - Mar Sun>=16 3:30 1:00 S diff --git a/time/australasia b/time/australasia index 11b0045a98..d981a6a916 100644 --- a/time/australasia +++ b/time/australasia @@ -1,4 +1,4 @@ -# @(#)australasia 7.33 +# @(#)australasia 7.34 # This file also includes Pacific islands. # Notes are at the end of this file @@ -768,6 +768,12 @@ Zone Pacific/Wallis 12:15:20 - LMT 1901 # Prem Bob Carr announced NSW will fall into line with other E states # and SA and continue daylight savings to the last Sun in Mar. +# From Eric Ulevik (1997-06-12): +# The NSW state government in Australia is talking about bringing the start +# of daylight savings time forward in the year 2000 to cater for the Olympics. +# This is going to take some time to be negotiated, because the plan is to do +# this in multiple states due to soccer games (which are not just in Sydney). + # Yancowinna # From John Basser (1989-01-04): diff --git a/time/europe b/time/europe index 6611520e98..c011424bdc 100644 --- a/time/europe +++ b/time/europe @@ -1,4 +1,4 @@ -# @(#)europe 7.44 +# @(#)europe 7.45 # This data is by no means authoritative; if you think you know better, # go ahead and edit the file (and please send any changes to @@ -829,7 +829,6 @@ Rule C-Eur 1916 only - Oct 1 1:00 0 - Rule C-Eur 1917 1918 - Apr Mon>=15 2:00s 1:00 S Rule C-Eur 1917 1918 - Sep Mon>=15 2:00s 0 - Rule C-Eur 1940 only - Apr 1 2:00s 1:00 S -# Whitman says 1941 DST was only from Feb 25 to Oct 5; go with Shanks. Rule C-Eur 1942 only - Nov 2 2:00s 0 - Rule C-Eur 1943 only - Mar 29 2:00s 1:00 S Rule C-Eur 1943 only - Oct 4 2:00s 0 - @@ -938,12 +937,11 @@ Rule Albania 1982 only - Oct 3 0:00 0 - Rule Albania 1983 only - Apr 18 0:00 1:00 S Rule Albania 1983 only - Oct 1 0:00 0 - Rule Albania 1984 only - Apr 1 0:00 1:00 S -Rule Albania 1984 only - Oct 1 0:00 0 - # Zone NAME GMTOFF RULES FORMAT [UNTIL] Zone Europe/Tirane 1:19:20 - LMT 1914 1:00 - CET 1940 Jun 16 - 1:00 Albania CE%sT 1985 Mar 31 1:00 - 1:00 W-Eur CE%sT 1991 +# The following transition is from Shanks's 4th edition (1995). + 1:00 Albania CE%sT 1984 Jul 1:00 EU CE%sT # Andorra @@ -984,50 +982,62 @@ Zone Europe/Minsk 1:50:16 - LMT 1880 2:00 Russia EE%sT # Belgium -# Whitman and Shanks disagree; go with Shanks, usually. +# +# From Paul Eggert (1997-07-02): +# Entries from 1918 through 1991 are taken from: +# Annuaire de L'Observatoire Royal de Belgique, +# Avenue Circulaire, 3, B-1180 BRUXELLES, CLVIIe annee, 1991 +# (Imprimerie HAYEZ, s.p.r.l., Rue Fin, 4, 1080 BRUXELLES, MCMXC), +# pp 8-9. +# LMT before 1892 was 0:17:30, according to the official journal of Belgium: +# Moniteur Belge, Samedi 30 Avril 1892, N.121. +# Thanks to Pascal Delmoitie for these references. +# The 1918 rules are listed for completeness; they apply to unoccupied Belgium. +# Assume Brussels switched to WET in 1918 when the armistice took effect. +# # Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S -# From Whitman: +Rule Belgium 1918 only - Mar 9 0:00s 1:00 S +Rule Belgium 1918 1919 - Oct Sat>=1 23:00s 0 - Rule Belgium 1919 only - Mar 1 23:00s 1:00 S -Rule Belgium 1919 only - Oct 4 23:00s 0 - -# Shanks gives 1920 Feb 14 23:00s; go with Whitman. -Rule Belgium 1920 1921 - Mar 14 23:00s 1:00 S +Rule Belgium 1920 only - Feb 14 23:00s 1:00 S Rule Belgium 1920 only - Oct 23 23:00s 0 - +Rule Belgium 1921 only - Mar 14 23:00s 1:00 S Rule Belgium 1921 only - Oct 25 23:00s 0 - Rule Belgium 1922 only - Mar 25 23:00s 1:00 S -# Whitman gives 1927 Oct 1 2:00s and 1928 Oct 7 2:00s; go with Shanks. -Rule Belgium 1922 1928 - Oct Sat>=1 23:00s 0 - +Rule Belgium 1922 1927 - Oct Sat>=1 23:00s 0 - Rule Belgium 1923 only - Apr 21 23:00s 1:00 S Rule Belgium 1924 only - Mar 29 23:00s 1:00 S Rule Belgium 1925 only - Apr 4 23:00s 1:00 S Rule Belgium 1926 only - Apr 17 23:00s 1:00 S Rule Belgium 1927 only - Apr 9 23:00s 1:00 S Rule Belgium 1928 only - Apr 14 23:00s 1:00 S +Rule Belgium 1928 1938 - Oct Sun>=2 2:00s 0 - Rule Belgium 1929 only - Apr 21 2:00s 1:00 S -Rule Belgium 1929 1938 - Oct Sun>=2 2:00s 0 - Rule Belgium 1930 only - Apr 13 2:00s 1:00 S Rule Belgium 1931 only - Apr 19 2:00s 1:00 S -Rule Belgium 1932 only - Apr 17 2:00s 1:00 S +Rule Belgium 1932 only - Apr 3 2:00s 1:00 S Rule Belgium 1933 only - Mar 26 2:00s 1:00 S Rule Belgium 1934 only - Apr 8 2:00s 1:00 S Rule Belgium 1935 only - Mar 31 2:00s 1:00 S Rule Belgium 1936 only - Apr 19 2:00s 1:00 S -# Whitman says 1937 Apr 18 2:00s; go with Shanks. Rule Belgium 1937 only - Apr 4 2:00s 1:00 S -# Whitman says 1938 Apr 10 2:00s; go with Shanks. Rule Belgium 1938 only - Mar 27 2:00s 1:00 S Rule Belgium 1939 only - Apr 16 2:00s 1:00 S Rule Belgium 1939 only - Nov 19 2:00s 0 - +Rule Belgium 1940 only - Feb 25 2:00s 1:00 S +Rule Belgium 1944 only - Sep 17 2:00s 0 - Rule Belgium 1945 only - Apr 2 2:00s 1:00 S Rule Belgium 1945 only - Sep 16 2:00s 0 - Rule Belgium 1946 only - May 19 2:00s 1:00 S Rule Belgium 1946 only - Oct 7 2:00s 0 - # Zone NAME GMTOFF RULES FORMAT [UNTIL] -Zone Europe/Brussels 0:17:20 - LMT 1880 - 0:17:20 - BMT 1892 May 1 12:00 # Brussels MT - 0:00 - WET 1914 Aug 4 - 1:00 C-Eur CE%sT 1919 Mar 1 23:00 - 0:00 Belgium WE%sT 1940 Feb 24 23:00 - 1:00 C-Eur CE%sT 1945 Apr 2 2:00 +Zone Europe/Brussels 0:17:30 - LMT 1880 + 0:17:30 - BMT 1892 May 1 12:00 # Brussels MT + 0:00 - WET 1914 Nov 8 + 1:00 - CET 1916 May 1 0:00 + 1:00 C-Eur CE%sT 1918 Nov 11 11:00u + 0:00 Belgium WE%sT 1940 May 20 2:00s + 1:00 C-Eur CE%sT 1944 Sep 3 1:00 Belgium CE%sT 1977 1:00 EU CE%sT diff --git a/time/iso3166.tab b/time/iso3166.tab index 3daf4abb8d..b5237783c4 100644 --- a/time/iso3166.tab +++ b/time/iso3166.tab @@ -51,8 +51,9 @@ BY Belarus BZ Belize CA Canada CC Cocos (Keeling) Islands +CD Congo (Dem. Rep.) CF Central African Rep. -CG Congo +CG Congo (Rep.) CH Switzerland CI Cote d'Ivoire CK Cook Islands @@ -103,7 +104,6 @@ GT Guatemala GU Guam GW Guinea-Bissau GY Guyana -HK Hong Kong HM Heard Island & McDonald Islands HN Honduras HR Croatia @@ -250,5 +250,4 @@ YT Mayotte YU Yugoslavia ZA South Africa ZM Zambia -ZR Zaire ZW Zimbabwe diff --git a/time/mktime.c b/time/mktime.c index d8fdf3a6c6..5012888967 100644 --- a/time/mktime.c +++ b/time/mktime.c @@ -22,7 +22,7 @@ /* #define DEBUG 1 */ #ifdef HAVE_CONFIG_H -#include +# include #endif #ifdef _LIBC @@ -35,50 +35,52 @@ If the host has a `zic' command with a `-L leapsecondfilename' option, then it supports leap seconds; otherwise it probably doesn't. */ #ifndef LEAP_SECONDS_POSSIBLE -#define LEAP_SECONDS_POSSIBLE 1 +# define LEAP_SECONDS_POSSIBLE 1 #endif #include /* Some systems define `time_t' here. */ #include #if HAVE_LIMITS_H -#include +# include #endif #if DEBUG -#include -#if STDC_HEADERS -#include -#endif +# include +# if STDC_HEADERS +# include +# endif /* Make it work even if the system's libc has its own mktime routine. */ -#define mktime my_mktime +# define mktime my_mktime #endif /* DEBUG */ #ifndef __P -#if defined (__GNUC__) || (defined (__STDC__) && __STDC__) -#define __P(args) args -#else -#define __P(args) () -#endif /* GCC. */ +# if defined (__GNUC__) || (defined (__STDC__) && __STDC__) +# define __P(args) args +# else +# define __P(args) () +# endif /* GCC. */ #endif /* Not __P. */ #ifndef CHAR_BIT -#define CHAR_BIT 8 +# define CHAR_BIT 8 #endif #ifndef INT_MIN -#define INT_MIN (~0 << (sizeof (int) * CHAR_BIT - 1)) +# define INT_MIN (~0 << (sizeof (int) * CHAR_BIT - 1)) #endif #ifndef INT_MAX -#define INT_MAX (~0 - INT_MIN) +# define INT_MAX (~0 - INT_MIN) #endif #ifndef TIME_T_MIN -#define TIME_T_MIN (0 < (time_t) -1 ? (time_t) 0 \ - : ~ (time_t) 0 << (sizeof (time_t) * CHAR_BIT - 1)) +/* The outer cast to time_t works around a bug in Cray C 5.0.3.0. */ +# define TIME_T_MIN ((time_t) \ + (0 < (time_t) -1 ? (time_t) 0 \ + : ~ (time_t) 0 << (sizeof (time_t) * CHAR_BIT - 1))) #endif #ifndef TIME_T_MAX -#define TIME_T_MAX (~ (time_t) 0 - TIME_T_MIN) +# define TIME_T_MAX (~ (time_t) 0 - TIME_T_MIN) #endif #define TM_YEAR_BASE 1900 @@ -87,7 +89,7 @@ #ifndef __isleap /* Nonzero if YEAR is a leap year (every 4 years, except every 100th isn't, and every 400th is). */ -#define __isleap(year) \ +# define __isleap(year) \ ((year) % 4 == 0 && ((year) % 100 != 0 || (year) % 400 == 0)) #endif @@ -107,11 +109,11 @@ time_t __mktime_internal __P ((struct tm *, #ifdef _LIBC -#define localtime_r __localtime_r +# define localtime_r __localtime_r #else -#if ! HAVE_LOCALTIME_R && ! defined (localtime_r) +# if ! HAVE_LOCALTIME_R && ! defined localtime_r /* Approximate localtime_r as best we can in its absence. */ -#define localtime_r my_localtime_r +# define localtime_r my_mktime_localtime_r static struct tm *localtime_r __P ((const time_t *, struct tm *)); static struct tm * localtime_r (t, tp) @@ -124,7 +126,7 @@ localtime_r (t, tp) *tp = *l; return tp; } -#endif /* ! HAVE_LOCALTIME_R && ! defined (localtime_r) */ +# endif /* ! HAVE_LOCALTIME_R && ! defined (localtime_r) */ #endif /* ! _LIBC */ diff --git a/time/private.h b/time/private.h index e32653b76d..7f98a67391 100644 --- a/time/private.h +++ b/time/private.h @@ -21,7 +21,7 @@ #ifndef lint #ifndef NOID -static char privatehid[] = "@(#)private.h 7.45"; +static char privatehid[] = "@(#)private.h 7.46"; #endif /* !defined NOID */ #endif /* !defined lint */ @@ -182,7 +182,7 @@ char * imalloc P((int n)); void * irealloc P((void * pointer, int size)); void icfree P((char * pointer)); void ifree P((char * pointer)); -char * scheck P((const char *string, const char *format)); +char * scheck P((const char *string, const char *format)); /* diff --git a/time/scheck.c b/time/scheck.c index 52b4ff51fd..39feeba701 100644 --- a/time/scheck.c +++ b/time/scheck.c @@ -1,6 +1,6 @@ #ifndef lint #ifndef NOID -static char elsieid[] = "@(#)scheck.c 8.14"; +static char elsieid[] = "@(#)scheck.c 8.15"; #endif /* !defined lint */ #endif /* !defined NOID */ diff --git a/time/strftime.c b/time/strftime.c index 4cb6c9e260..891d301f5c 100644 --- a/time/strftime.c +++ b/time/strftime.c @@ -31,7 +31,6 @@ # define HAVE_TZSET 1 # define MULTIBYTE_IS_FORMAT_SAFE 1 # define STDC_HEADERS 1 -# include # include "../locale/localeinfo.h" #endif @@ -81,7 +80,9 @@ extern char *tzname[]; # include # include #else -# define memcpy(d, s, n) bcopy ((s), (d), (n)) +# ifndef HAVE_MEMCPY +# define memcpy(d, s, n) bcopy ((s), (d), (n)) +# endif #endif #ifndef __P @@ -138,7 +139,7 @@ extern int __tz_compute __P ((time_t timer, const struct tm *tm)); # if ! HAVE_LOCALTIME_R # if ! HAVE_TM_GMTOFF /* Approximate gmtime_r as best we can in its absence. */ -# define gmtime_r my_gmtime_r +# define gmtime_r my_gmtime_r static struct tm *gmtime_r __P ((const time_t *, struct tm *)); static struct tm * gmtime_r (t, tp) @@ -154,7 +155,7 @@ gmtime_r (t, tp) # endif /* ! HAVE_TM_GMTOFF */ /* Approximate localtime_r as best we can in its absence. */ -# define localtime_r my_localtime_r +# define localtime_r my_ftime_localtime_r static struct tm *localtime_r __P ((const time_t *, struct tm *)); static struct tm * localtime_r (t, tp) @@ -171,11 +172,15 @@ localtime_r (t, tp) #endif /* ! defined (_LIBC) */ -#if !defined (memset) && !defined (HAVE_MEMSET) && !defined (_LIBC) +#if !defined memset && !defined HAVE_MEMSET && !defined _LIBC /* Some systems lack the `memset' function and we don't want to introduce additional dependencies. */ -static const char spaces[16] = " "; -static const char zeroes[16] = "0000000000000000"; +/* The SGI compiler reportedly barfs on the trailing null + if we use a string constant as the initializer. 28 June 1997, rms. */ +static const char spaces[16] = /* " " */ + { ' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ' }; +static const char zeroes[16] = /* "0000000000000000" */ + { '0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0' }; # define memset_space(P, Len) \ do { \ @@ -209,7 +214,7 @@ static const char zeroes[16] = "0000000000000000"; # define memset_zero(P, Len) (memset ((P), '0', (Len)), (P) += (Len)) #endif -#define add(n, f) \ +#define add(n, f) \ do \ { \ int _n = (n); \ @@ -232,7 +237,7 @@ static const char zeroes[16] = "0000000000000000"; i += _incr; \ } while (0) -#define cpy(n, s) \ +#define cpy(n, s) \ add ((n), \ if (to_lowcase) \ memcpy_lowcase (p, (s), _n); \ @@ -282,9 +287,11 @@ memcpy_uppcase (dest, src, len) return dest; } + #if ! HAVE_TM_GMTOFF /* Yield the difference between *A and *B, measured in seconds, ignoring leap seconds. */ +# define tm_diff ftime_tm_diff static int tm_diff __P ((const struct tm *, const struct tm *)); static int tm_diff (a, b) @@ -417,15 +424,13 @@ strftime (s, maxsize, format, tp) const char *f; zone = NULL; -#if !defined _LIBC && HAVE_TM_ZONE - /* XXX We have some problems here. First, the string pointed to by - tm_zone is dynamically allocated while loading the zone data. But - when another zone is loaded since the information in TP were - computed this would be a stale pointer. - The second problem is the POSIX test suite which assumes setting +#if HAVE_TM_ZONE + /* The POSIX test suite assumes that setting the environment variable TZ to a new value before calling strftime() will influence the result (the %Z format) even if the information in - TP is computed with a totally different time zone. --drepper@gnu */ + TP is computed with a totally different time zone. + This is bogus: though POSIX allows bad behavior like this, + POSIX does not require it. Do the right thing instead. */ zone = (const char *) tp->tm_zone; #endif #if HAVE_TZNAME @@ -464,6 +469,7 @@ strftime (s, maxsize, format, tp) int width = -1; int to_lowcase = 0; int to_uppcase = 0; + int change_case = 0; #if DO_MULTIBYTE @@ -555,6 +561,9 @@ strftime (s, maxsize, format, tp) case '^': to_uppcase = 1; continue; + case '#': + change_case = 1; + continue; default: break; @@ -592,9 +601,11 @@ strftime (s, maxsize, format, tp) switch (*f) { #define DO_NUMBER(d, v) \ - digits = d; number_value = v; goto do_number + digits = width == -1 ? d : width; \ + number_value = v; goto do_number #define DO_NUMBER_SPACEPAD(d, v) \ - digits = d; number_value = v; goto do_number_spacepad + digits = width == -1 ? d : width; \ + number_value = v; goto do_number_spacepad case '%': if (modifier != 0) @@ -605,12 +616,22 @@ strftime (s, maxsize, format, tp) case 'a': if (modifier != 0) goto bad_format; + if (change_case) + { + to_uppcase = 1; + to_lowcase = 0; + } cpy (aw_len, a_wkday); break; case 'A': if (modifier != 0) goto bad_format; + if (change_case) + { + to_uppcase = 1; + to_lowcase = 0; + } cpy (wkday_len, f_wkday); break; @@ -624,6 +645,11 @@ strftime (s, maxsize, format, tp) case 'B': if (modifier != 0) goto bad_format; + if (change_case) + { + to_uppcase = 1; + to_lowcase = 0; + } cpy (month_len, f_month); break; @@ -824,6 +850,11 @@ strftime (s, maxsize, format, tp) /* FALLTHROUGH */ case 'p': + if (change_case) + { + to_uppcase = 0; + to_lowcase = 1; + } cpy (ap_len, ampm); break; @@ -996,6 +1027,11 @@ strftime (s, maxsize, format, tp) DO_NUMBER (2, (tp->tm_year % 100 + 100) % 100); case 'Z': + if (change_case) + { + to_uppcase = 0; + to_lowcase = 1; + } cpy (zonelen, zone); break; diff --git a/time/strptime.c b/time/strptime.c index 90b88a1ba3..8d650716fe 100644 --- a/time/strptime.c +++ b/time/strptime.c @@ -541,7 +541,10 @@ strptime_internal (buf, format, tm, decided) break; case 'Y': /* Match year including century number. */ - get_number (0, INT_MAX); + if (sizeof (time_t) > 4) + get_number (0, 9999); + else + get_number (0, 2036); tm->tm_year = val - 1900; break; case 'Z': diff --git a/time/tzfile.c b/time/tzfile.c index 44b33cb02c..88e86e33b1 100644 --- a/time/tzfile.c +++ b/time/tzfile.c @@ -43,6 +43,8 @@ struct leap long int change; /* Seconds of correction to apply. */ }; +extern const char * __tzstring (const char *); /* Defined in tzset.c. */ + static struct ttinfo *find_transition (time_t timer); static void compute_tzname_max (size_t); @@ -244,7 +246,7 @@ __tzfile_read (const char *file) for (i = 0; i < num_isstd; ++i) { - char c = getc (f); + int c = getc (f); if (c == EOF) goto lose; types[i].isstd = c != 0; @@ -254,7 +256,7 @@ __tzfile_read (const char *file) for (i = 0; i < num_isgmt; ++i) { - char c = getc (f); + int c = getc (f); if (c == EOF) goto lose; types[i].isgmt = c != 0; @@ -267,9 +269,9 @@ __tzfile_read (const char *file) info = find_transition (0); for (i = 0; i < num_types && i < sizeof (__tzname) / sizeof (__tzname[0]); ++i) - __tzname[types[i].isdst] = &zone_names[types[i].idx]; + __tzname[types[i].isdst] = __tzstring (&zone_names[types[i].idx]); if (info->isdst < sizeof (__tzname) / sizeof (__tzname[0])) - __tzname[info->isdst] = &zone_names[info->idx]; + __tzname[info->isdst] = __tzstring (&zone_names[info->idx]); compute_tzname_max (chars); @@ -285,7 +287,8 @@ __tzfile_read (const char *file) from the TZDEFRULES file. */ void -__tzfile_default (char *std, char *dst, long int stdoff, long int dstoff) +__tzfile_default (const char *std, const char *dst, + long int stdoff, long int dstoff) { size_t stdlen, dstlen, i; long int rule_offset, rule_stdoff, rule_dstoff; @@ -372,8 +375,8 @@ __tzfile_default (char *std, char *dst, long int stdoff, long int dstoff) types[1].isdst = 1; /* Reset the zone names to point to the user's names. */ - __tzname[0] = &zone_names[0]; - __tzname[1] = &zone_names[stdlen]; + __tzname[0] = (char *) std; + __tzname[1] = (char *) dst; compute_tzname_max (stdlen + dstlen); } @@ -455,7 +458,7 @@ __tzfile_compute (time_t timer, long int *leap_correct, int *leap_hit) void compute_tzname_max (size_t chars) { - extern size_t __tzname_cur_max; /* Defined in __tzset.c. */ + extern size_t __tzname_cur_max; /* Defined in tzset.c. */ const char *p; diff --git a/time/tzset.c b/time/tzset.c index 05760b2c62..ca05fa81c5 100644 --- a/time/tzset.c +++ b/time/tzset.c @@ -31,8 +31,9 @@ extern const unsigned short int __mon_yday[2][13]; extern int __use_tzfile; extern void __tzfile_read __P ((const char *file)); -extern void __tzfile_default __P ((char *std, char *dst, +extern void __tzfile_default __P ((const char *std, const char *dst, long int stdoff, long int dstoff)); +extern const char * __tzstring __P ((const char *string)); extern int __tz_compute __P ((time_t timer, const struct tm *tm)); char *__tzname[2] = { (char *) "GMT", (char *) "GMT" }; @@ -53,7 +54,7 @@ weak_alias (__timezone, timezone) timezone given in the POSIX standard TZ envariable. */ typedef struct { - char *name; + const char *name; /* When to change. */ enum { J0, J1, M } type; /* Interpretation of: */ @@ -74,6 +75,68 @@ static tz_rule tz_rules[2]; static int compute_change __P ((tz_rule *rule, int year)); +/* Header for a list of buffers containing time zone strings. */ +struct tzstring_head +{ + struct tzstring_head *next; + /* The buffer itself immediately follows the header. + The buffer contains zero or more (possibly overlapping) strings. + The last string is followed by 2 '\0's instead of the usual 1. */ +}; + +/* First in a list of buffers containing time zone strings. + All the buffers but the last are read-only. */ +static struct +{ + struct tzstring_head head; + char data[48]; +} tzstring_list; + +/* Size of the last buffer in the list, not counting its header. */ +static size_t tzstring_last_buffer_size = sizeof tzstring_list.data; + +/* Allocate a time zone string with given contents. + The string will never be moved or deallocated. + However, its contents may be shared with other such strings. */ +const char * +__tzstring (string) + const char *string; +{ + struct tzstring_head *h = &tzstring_list.head; + size_t needed; + char *p; + + /* Look through time zone string list for a duplicate of this one. */ + for (h = &tzstring_list.head; ; h = h->next) + { + for (p = (char *) (h + 1); p[0] | p[1]; p++) + if (strcmp (p, string) == 0) + return p; + if (! h->next) + break; + } + + /* No duplicate was found. Copy to the end of this buffer if there's room; + otherwise, append a large-enough new buffer to the list and use it. */ + p++; + needed = strlen (string) + 2; /* Need 2 trailing '\0's after last string. */ + + if ((size_t) ((char *) (h + 1) + tzstring_last_buffer_size - p) < needed) + { + size_t buffer_size = tzstring_last_buffer_size; + while ((buffer_size *= 2) < needed) + continue; + if (! (h = h->next = malloc (sizeof *h + buffer_size))) + return NULL; + h->next = NULL; + tzstring_last_buffer_size = buffer_size; + p = (char *) (h + 1); + } + + strncpy (p, string, needed); + return p; +} + static char *old_tz = NULL; /* Interpret the TZ envariable. */ @@ -85,6 +148,7 @@ __tzset_internal (always) static int is_initialized = 0; register const char *tz; register size_t l; + char *tzbuf; unsigned short int hh, mm, ss; unsigned short int whichrule; @@ -112,12 +176,6 @@ __tzset_internal (always) /* No change, simply return. */ return; - /* Free old storage. */ - if (tz_rules[0].name != NULL && *tz_rules[0].name != '\0') - free ((void *) tz_rules[0].name); - if (tz_rules[1].name != NULL && *tz_rules[1].name != '\0' && - tz_rules[1].name != tz_rules[0].name) - free ((void *) tz_rules[1].name); tz_rules[0].name = NULL; tz_rules[1].name = NULL; @@ -135,16 +193,7 @@ __tzset_internal (always) if (tz == NULL || *tz == '\0') { - static const char UTC[] = "UTC"; - size_t len = sizeof UTC; - tz_rules[0].name = (char *) malloc (len); - if (tz_rules[0].name == NULL) - return; - tz_rules[1].name = (char *) malloc (len); - if (tz_rules[1].name == NULL) - return; - memcpy ((void *) tz_rules[0].name, UTC, len); - memcpy ((void *) tz_rules[1].name, UTC, len); + tz_rules[0].name = tz_rules[1].name = "UTC"; tz_rules[0].type = tz_rules[1].type = J0; tz_rules[0].m = tz_rules[0].n = tz_rules[0].d = 0; tz_rules[1].m = tz_rules[1].n = tz_rules[1].d = 0; @@ -157,11 +206,11 @@ __tzset_internal (always) /* Clear out old state and reset to unnamed UTC. */ memset (tz_rules, 0, sizeof tz_rules); - tz_rules[0].name = tz_rules[1].name = (char *) ""; + tz_rules[0].name = tz_rules[1].name = ""; /* Get the standard timezone name. */ - tz_rules[0].name = (char *) malloc (strlen (tz) + 1); - if (tz_rules[0].name == NULL) + tzbuf = malloc (strlen (tz) + 1); + if (! tzbuf) { /* Clear the old tz name so we will try again. */ free (old_tz); @@ -169,25 +218,23 @@ __tzset_internal (always) return; } - if (sscanf (tz, "%[^0-9,+-]", tz_rules[0].name) != 1 || - (l = strlen(tz_rules[0].name)) < 3) + if (sscanf (tz, "%[^0-9,+-]", tzbuf) != 1 || + (l = strlen (tzbuf)) < 3) { - free (tz_rules[0].name); - tz_rules[0].name = (char *) ""; + free (tzbuf); return; } - { - char *n = realloc ((void *) tz_rules[0].name, l + 1); - if (n != NULL) - tz_rules[0].name = n; - } + tz_rules[0].name = __tzstring (tzbuf); tz += l; /* Figure out the standard offset from UTC. */ if (*tz == '\0' || (*tz != '+' && *tz != '-' && !isdigit (*tz))) - return; + { + free (tzbuf); + return; + } if (*tz == '-' || *tz == '+') tz_rules[0].offset = *tz++ == '-' ? 1L : -1L; @@ -196,6 +243,7 @@ __tzset_internal (always) switch (sscanf (tz, "%hu:%hu:%hu", &hh, &mm, &ss)) { default: + free (tzbuf); return; case 1: mm = 0; @@ -218,23 +266,14 @@ __tzset_internal (always) /* Get the DST timezone name (if any). */ if (*tz != '\0') { - char *n = malloc (strlen (tz) + 1); - if (n != NULL) - { - tz_rules[1].name = n; - if (sscanf (tz, "%[^0-9,+-]", tz_rules[1].name) != 1 || - (l = strlen (tz_rules[1].name)) < 3) - { - free (n); - tz_rules[1].name = (char *) ""; - goto done_names; /* Punt on name, set up the offsets. */ - } - n = realloc ((void *) tz_rules[1].name, l + 1); - if (n != NULL) - tz_rules[1].name = n; + char *n = tzbuf + strlen (tzbuf) + 1; + if (sscanf (tz, "%[^0-9,+-]", n) != 1 || + (l = strlen (n)) < 3) + goto done_names; /* Punt on name, set up the offsets. */ - tz += l; - } + tz_rules[1].name = __tzstring (n); + + tz += l; /* Figure out the DST offset from GMT. */ if (*tz == '-' || *tz == '+') @@ -271,6 +310,7 @@ __tzset_internal (always) tz_rules[1].name = tz_rules[0].name; done_names: + free (tzbuf); if (*tz == '\0' || (tz[0] == ',' && tz[1] == '\0')) { diff --git a/time/zone.tab b/time/zone.tab index 074749916a..48b32373cc 100644 --- a/time/zone.tab +++ b/time/zone.tab @@ -101,6 +101,8 @@ CA +4916-12307 America/Vancouver Pacific Time - west British Columbia CA +6043-13503 America/Whitehorse Pacific Time - south Yukon CA +6404-13925 America/Dawson Pacific Time - north Yukon CC -1210+09655 Indian/Cocos +CD -0418+01518 Africa/Kinshasa west Dem. Rep. of Congo +CD -1140+02728 Africa/Lubumbashi east Dem. Rep. of Congo CF +0422+01835 Africa/Bangui CG -0416+01517 Africa/Brazzaville CH +4723+00832 Europe/Zurich @@ -111,6 +113,7 @@ CL -2710-10927 Pacific/Easter Easter Island CM +0403+00942 Africa/Douala CN +4545+12641 Asia/Harbin north Manchuria CN +3114+12128 Asia/Shanghai China coast +CN +2217+11409 Asia/Hong_Kong Hong Kong CN +2934+10635 Asia/Chungking China mountains CN +4348+08735 Asia/Urumqi Tibet & Xinjiang CN +3929+07559 Asia/Kashgar Eastern Turkestan @@ -167,7 +170,6 @@ GT +1438-09031 America/Guatemala GU +1328+14445 Pacific/Guam GW +1151-01535 Africa/Bissau GY +0648-05810 America/Guyana -HK +2217+11409 Asia/Hong_Kong HN +1406-08713 America/Tegucigalpa HR +4548+01558 Europe/Zagreb HT +1832-07220 America/Port-au-Prince @@ -366,6 +368,4 @@ YT -1247+04514 Indian/Mayotte YU +4450+02030 Europe/Belgrade ZA -2615+02800 Africa/Johannesburg ZM -1525+02817 Africa/Lusaka -ZR -0418+01518 Africa/Kinshasa west Zaire -ZR -1140+02728 Africa/Lubumbashi east Zaire ZW -1750+03103 Africa/Harare -- cgit v1.2.3