mirror of
https://sourceware.org/git/glibc.git
synced 2025-01-18 06:30:05 +00:00
* include/time.h: Declare __tzset_parse_tz and __tzset_compute.
* time/tzset.c (tzset_internal): Break TZ string parsing out into __tzset_parse_tz and updating of daylight, timezone, tzname into update_vars. (__tz_compute): Renamed from tz_compute. Take additional parameters. (__tz_convert): Updating of tm_isdst, tm_zone, and tm_gmtoff now happens in __tz_compute. * time/tzfile.c (__tzfile_read): Also read TZ string. (find_transition): Fold into __tzfile_compute. (__tzfile_compute): For times beyond the last transition try to use the TZ string. * timezone/tst-timezone.c: Information in daylight and tzname does change for Asia/Tokyo timezone with more concrete information. Remove the test. * include/stdio.h: Add libc_hidden_proto for ftello. * libio/ftello.c: Add libc_hidden_def.
This commit is contained in:
parent
89dc9d4c5b
commit
fa76dde2cf
18
ChangeLog
18
ChangeLog
@ -1,5 +1,23 @@
|
|||||||
2007-10-14 Ulrich Drepper <drepper@redhat.com>
|
2007-10-14 Ulrich Drepper <drepper@redhat.com>
|
||||||
|
|
||||||
|
* include/time.h: Declare __tzset_parse_tz and __tzset_compute.
|
||||||
|
* time/tzset.c (tzset_internal): Break TZ string parsing out into
|
||||||
|
__tzset_parse_tz and updating of daylight, timezone, tzname into
|
||||||
|
update_vars.
|
||||||
|
(__tz_compute): Renamed from tz_compute. Take additional parameters.
|
||||||
|
(__tz_convert): Updating of tm_isdst, tm_zone, and tm_gmtoff now
|
||||||
|
happens in __tz_compute.
|
||||||
|
* time/tzfile.c (__tzfile_read): Also read TZ string.
|
||||||
|
(find_transition): Fold into __tzfile_compute.
|
||||||
|
(__tzfile_compute): For times beyond the last transition try to
|
||||||
|
use the TZ string.
|
||||||
|
* timezone/tst-timezone.c: Information in daylight and tzname does
|
||||||
|
change for Asia/Tokyo timezone with more concrete information.
|
||||||
|
Remove the test.
|
||||||
|
|
||||||
|
* include/stdio.h: Add libc_hidden_proto for ftello.
|
||||||
|
* libio/ftello.c: Add libc_hidden_def.
|
||||||
|
|
||||||
[BZ #1140]
|
[BZ #1140]
|
||||||
* time/tzfile.c (__tzfile_compute): Compute tzname[] values based
|
* time/tzfile.c (__tzfile_compute): Compute tzname[] values based
|
||||||
on the specified time and not the last entries in the file. Move
|
on the specified time and not the last entries in the file. Move
|
||||||
|
@ -138,6 +138,7 @@ libc_hidden_proto (rewind)
|
|||||||
libc_hidden_proto (fileno)
|
libc_hidden_proto (fileno)
|
||||||
libc_hidden_proto (fwrite)
|
libc_hidden_proto (fwrite)
|
||||||
libc_hidden_proto (fseek)
|
libc_hidden_proto (fseek)
|
||||||
|
libc_hidden_proto (ftello)
|
||||||
libc_hidden_proto (fflush_unlocked)
|
libc_hidden_proto (fflush_unlocked)
|
||||||
libc_hidden_proto (fread_unlocked)
|
libc_hidden_proto (fread_unlocked)
|
||||||
libc_hidden_proto (fwrite_unlocked)
|
libc_hidden_proto (fwrite_unlocked)
|
||||||
|
@ -46,6 +46,9 @@ extern void __tzfile_compute (time_t timer, int use_localtime,
|
|||||||
struct tm *tp);
|
struct tm *tp);
|
||||||
extern void __tzfile_default (const char *std, const char *dst,
|
extern void __tzfile_default (const char *std, const char *dst,
|
||||||
long int stdoff, long int dstoff);
|
long int stdoff, long int dstoff);
|
||||||
|
extern void __tzset_parse_tz (const char *tz);
|
||||||
|
extern void __tz_compute (time_t timer, struct tm *tm, int use_localtime)
|
||||||
|
__THROW internal_function;
|
||||||
|
|
||||||
/* Subroutine of `mktime'. Return the `time_t' representation of TP and
|
/* Subroutine of `mktime'. Return the `time_t' representation of TP and
|
||||||
normalize TP, given that a `struct tm *' maps to a `time_t' as performed
|
normalize TP, given that a `struct tm *' maps to a `time_t' as performed
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* Copyright (C) 1993, 1995-2001, 2002, 2003, 2004
|
/* Copyright (C) 1993, 1995-2001, 2002, 2003, 2004, 2007
|
||||||
Free Software Foundation, Inc.
|
Free Software Foundation, Inc.
|
||||||
This file is part of the GNU C Library.
|
This file is part of the GNU C Library.
|
||||||
|
|
||||||
@ -63,3 +63,4 @@ ftello (fp)
|
|||||||
}
|
}
|
||||||
return pos;
|
return pos;
|
||||||
}
|
}
|
||||||
|
libc_hidden_def (ftello)
|
||||||
|
@ -264,9 +264,9 @@ nscd_getgr_r (const char *key, size_t keylen, request_type type,
|
|||||||
retval = 0;
|
retval = 0;
|
||||||
|
|
||||||
/* If there are no group members TOTAL_LEN is zero. */
|
/* If there are no group members TOTAL_LEN is zero. */
|
||||||
if (total_len > 0)
|
if (gr_name == NULL)
|
||||||
{
|
{
|
||||||
if (gr_name == NULL)
|
if (total_len > 0)
|
||||||
{
|
{
|
||||||
size_t n = __readall (sock, resultbuf->gr_mem[0], total_len);
|
size_t n = __readall (sock, resultbuf->gr_mem[0], total_len);
|
||||||
if (__builtin_expect (n != total_len, 0))
|
if (__builtin_expect (n != total_len, 0))
|
||||||
@ -278,26 +278,26 @@ nscd_getgr_r (const char *key, size_t keylen, request_type type,
|
|||||||
else
|
else
|
||||||
*result = resultbuf;
|
*result = resultbuf;
|
||||||
}
|
}
|
||||||
else
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Copy the group member names. */
|
||||||
|
memcpy (resultbuf->gr_mem[0], gr_name + gr_name_len, total_len);
|
||||||
|
|
||||||
|
/* Try to detect corrupt databases. */
|
||||||
|
if (resultbuf->gr_name[gr_name_len - 1] != '\0'
|
||||||
|
|| resultbuf->gr_passwd[gr_resp.gr_passwd_len - 1] != '\0'
|
||||||
|
|| ({for (cnt = 0; cnt < gr_resp.gr_mem_cnt; ++cnt)
|
||||||
|
if (resultbuf->gr_mem[cnt][len[cnt] - 1] != '\0')
|
||||||
|
break;
|
||||||
|
cnt < gr_resp.gr_mem_cnt; }))
|
||||||
{
|
{
|
||||||
/* Copy the group member names. */
|
/* We cannot use the database. */
|
||||||
memcpy (resultbuf->gr_mem[0], gr_name + gr_name_len, total_len);
|
retval = mapped->head->gc_cycle != gc_cycle ? -2 : -1;
|
||||||
|
goto out_close;
|
||||||
/* Try to detect corrupt databases. */
|
|
||||||
if (resultbuf->gr_name[gr_name_len - 1] != '\0'
|
|
||||||
|| resultbuf->gr_passwd[gr_resp.gr_passwd_len - 1] != '\0'
|
|
||||||
|| ({for (cnt = 0; cnt < gr_resp.gr_mem_cnt; ++cnt)
|
|
||||||
if (resultbuf->gr_mem[cnt][len[cnt] - 1] != '\0')
|
|
||||||
break;
|
|
||||||
cnt < gr_resp.gr_mem_cnt; }))
|
|
||||||
{
|
|
||||||
/* We cannot use the database. */
|
|
||||||
retval = mapped->head->gc_cycle != gc_cycle ? -2 : -1;
|
|
||||||
goto out_close;
|
|
||||||
}
|
|
||||||
|
|
||||||
*result = resultbuf;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
*result = resultbuf;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
287
time/tzfile.c
287
time/tzfile.c
@ -62,6 +62,7 @@ static long int rule_stdoff;
|
|||||||
static long int rule_dstoff;
|
static long int rule_dstoff;
|
||||||
static size_t num_leaps;
|
static size_t num_leaps;
|
||||||
static struct leap *leaps;
|
static struct leap *leaps;
|
||||||
|
static char *tzspec;
|
||||||
|
|
||||||
#include <endian.h>
|
#include <endian.h>
|
||||||
#include <byteswap.h>
|
#include <byteswap.h>
|
||||||
@ -113,6 +114,7 @@ __tzfile_read (const char *file, size_t extra, char **extrap)
|
|||||||
size_t leaps_idx;
|
size_t leaps_idx;
|
||||||
int was_using_tzfile = __use_tzfile;
|
int was_using_tzfile = __use_tzfile;
|
||||||
int trans_width = 4;
|
int trans_width = 4;
|
||||||
|
size_t tzspec_len;
|
||||||
|
|
||||||
if (sizeof (time_t) != 4 && sizeof (time_t) != 8)
|
if (sizeof (time_t) != 4 && sizeof (time_t) != 8)
|
||||||
abort ();
|
abort ();
|
||||||
@ -241,10 +243,18 @@ __tzfile_read (const char *file, size_t extra, char **extrap)
|
|||||||
& ~(__alignof__ (struct leap) - 1));
|
& ~(__alignof__ (struct leap) - 1));
|
||||||
leaps_idx = total_size;
|
leaps_idx = total_size;
|
||||||
total_size += num_leaps * sizeof (struct leap);
|
total_size += num_leaps * sizeof (struct leap);
|
||||||
|
tzspec_len = (trans_width == 8
|
||||||
|
? st.st_size - (ftello (f)
|
||||||
|
+ num_transitions * (8 + 1)
|
||||||
|
+ num_types * 6
|
||||||
|
+ chars
|
||||||
|
+ num_leaps * 8
|
||||||
|
+ num_isstd
|
||||||
|
+ num_isgmt) - 1 : 0);
|
||||||
|
|
||||||
/* Allocate enough memory including the extra block requested by the
|
/* Allocate enough memory including the extra block requested by the
|
||||||
caller. */
|
caller. */
|
||||||
transitions = (time_t *) malloc (total_size + extra);
|
transitions = (time_t *) malloc (total_size + tzspec_len + extra);
|
||||||
if (transitions == NULL)
|
if (transitions == NULL)
|
||||||
goto lose;
|
goto lose;
|
||||||
|
|
||||||
@ -253,6 +263,10 @@ __tzfile_read (const char *file, size_t extra, char **extrap)
|
|||||||
types = (struct ttinfo *) ((char *) transitions + types_idx);
|
types = (struct ttinfo *) ((char *) transitions + types_idx);
|
||||||
zone_names = (char *) types + num_types * sizeof (struct ttinfo);
|
zone_names = (char *) types + num_types * sizeof (struct ttinfo);
|
||||||
leaps = (struct leap *) ((char *) transitions + leaps_idx);
|
leaps = (struct leap *) ((char *) transitions + leaps_idx);
|
||||||
|
if (trans_width == 8)
|
||||||
|
tzspec = (char *) leaps + num_leaps * sizeof (struct leap);
|
||||||
|
else
|
||||||
|
tzspec = NULL;
|
||||||
if (extra > 0)
|
if (extra > 0)
|
||||||
*extrap = (char *) &leaps[num_leaps];
|
*extrap = (char *) &leaps[num_leaps];
|
||||||
|
|
||||||
@ -356,11 +370,16 @@ __tzfile_read (const char *file, size_t extra, char **extrap)
|
|||||||
while (i < num_types)
|
while (i < num_types)
|
||||||
types[i++].isgmt = 0;
|
types[i++].isgmt = 0;
|
||||||
|
|
||||||
/* XXX When a version 2 file is available it can contain a POSIX TZ-style
|
/* Read the POSIX TZ-style information if possible. */
|
||||||
formatted string which specifies how times past the last one specified
|
if (tzspec != NULL)
|
||||||
are supposed to be handled. We might want to handle this at some
|
{
|
||||||
point. But it might be overhead since most/all? files have an
|
/* Skip over the newline first. */
|
||||||
open-ended last entry. */
|
if (getc_unlocked (f) != '\n'
|
||||||
|
|| fread_unlocked (tzspec, 1, tzspec_len - 1, f) != tzspec_len - 1)
|
||||||
|
tzspec = NULL;
|
||||||
|
else
|
||||||
|
tzspec[tzspec_len - 1] = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
fclose (f);
|
fclose (f);
|
||||||
|
|
||||||
@ -530,128 +549,6 @@ __tzfile_default (const char *std, const char *dst,
|
|||||||
compute_tzname_max (stdlen + dstlen);
|
compute_tzname_max (stdlen + dstlen);
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct ttinfo *
|
|
||||||
internal_function
|
|
||||||
find_transition (time_t timer)
|
|
||||||
{
|
|
||||||
size_t i;
|
|
||||||
|
|
||||||
__tzname[0] = NULL;
|
|
||||||
__tzname[1] = NULL;
|
|
||||||
|
|
||||||
if (num_transitions == 0 || timer < transitions[0])
|
|
||||||
{
|
|
||||||
/* TIMER is before any transition (or there are no transitions).
|
|
||||||
Choose the first non-DST type
|
|
||||||
(or the first if they're all DST types). */
|
|
||||||
i = 0;
|
|
||||||
while (i < num_types && types[i].isdst)
|
|
||||||
{
|
|
||||||
if (__tzname[1] == NULL)
|
|
||||||
__tzname[1] = __tzstring (&zone_names[types[i].idx]);
|
|
||||||
|
|
||||||
++i;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (i == num_types)
|
|
||||||
i = 0;
|
|
||||||
__tzname[0] = __tzstring (&zone_names[types[i].idx]);
|
|
||||||
if (__tzname[1] == NULL)
|
|
||||||
{
|
|
||||||
size_t j = i;
|
|
||||||
while (j < num_types)
|
|
||||||
if (types[j].isdst)
|
|
||||||
{
|
|
||||||
__tzname[1] = __tzstring (&zone_names[types[j].idx]);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
++j;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (timer >= transitions[num_transitions - 1])
|
|
||||||
{
|
|
||||||
i = num_transitions - 1;
|
|
||||||
goto found;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* Find the first transition after TIMER, and
|
|
||||||
then pick the type of the transition before it. */
|
|
||||||
size_t lo = 0;
|
|
||||||
size_t hi = num_transitions - 1;
|
|
||||||
/* Assume that DST is changing twice a year and guess initial
|
|
||||||
search spot from it.
|
|
||||||
Half of a gregorian year has on average 365.2425 * 86400 / 2
|
|
||||||
= 15778476 seconds. */
|
|
||||||
i = (transitions[num_transitions - 1] - timer) / 15778476;
|
|
||||||
if (i < num_transitions)
|
|
||||||
{
|
|
||||||
i = num_transitions - 1 - i;
|
|
||||||
if (timer < transitions[i])
|
|
||||||
{
|
|
||||||
if (i < 10 || timer >= transitions[i - 10])
|
|
||||||
{
|
|
||||||
/* Linear search. */
|
|
||||||
while (timer < transitions[i - 1])
|
|
||||||
--i;
|
|
||||||
goto found;
|
|
||||||
}
|
|
||||||
hi = i - 10;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (i + 10 >= num_transitions || timer < transitions[i + 10])
|
|
||||||
{
|
|
||||||
/* Linear search. */
|
|
||||||
while (timer >= transitions[i])
|
|
||||||
++i;
|
|
||||||
goto found;
|
|
||||||
}
|
|
||||||
lo = i + 10;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Binary search. */
|
|
||||||
/* assert (timer >= transitions[lo] && timer < transitions[hi]); */
|
|
||||||
while (lo + 1 < hi)
|
|
||||||
{
|
|
||||||
i = (lo + hi) / 2;
|
|
||||||
if (timer < transitions[i])
|
|
||||||
hi = i;
|
|
||||||
else
|
|
||||||
lo = i;
|
|
||||||
}
|
|
||||||
i = hi;
|
|
||||||
|
|
||||||
found:
|
|
||||||
/* assert (timer >= transitions[i - 1] && timer < transitions[i]); */
|
|
||||||
__tzname[types[type_idxs[i - 1]].isdst]
|
|
||||||
= __tzstring (&zone_names[types[type_idxs[i - 1]].idx]);
|
|
||||||
size_t j = i;
|
|
||||||
while (j < num_transitions)
|
|
||||||
{
|
|
||||||
int type = type_idxs[j];
|
|
||||||
int dst = types[type].isdst;
|
|
||||||
int idx = types[type].idx;
|
|
||||||
|
|
||||||
if (__tzname[dst] == NULL)
|
|
||||||
{
|
|
||||||
__tzname[dst] = __tzstring (&zone_names[idx]);
|
|
||||||
|
|
||||||
if (__tzname[1 - dst] != NULL)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
++j;
|
|
||||||
}
|
|
||||||
|
|
||||||
i = type_idxs[i - 1];
|
|
||||||
}
|
|
||||||
|
|
||||||
return &types[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
__tzfile_compute (time_t timer, int use_localtime,
|
__tzfile_compute (time_t timer, int use_localtime,
|
||||||
long int *leap_correct, int *leap_hit,
|
long int *leap_correct, int *leap_hit,
|
||||||
@ -661,7 +558,139 @@ __tzfile_compute (time_t timer, int use_localtime,
|
|||||||
|
|
||||||
if (use_localtime)
|
if (use_localtime)
|
||||||
{
|
{
|
||||||
struct ttinfo *info = find_transition (timer);
|
__tzname[0] = NULL;
|
||||||
|
__tzname[1] = NULL;
|
||||||
|
|
||||||
|
if (num_transitions == 0 || timer < transitions[0])
|
||||||
|
{
|
||||||
|
/* TIMER is before any transition (or there are no transitions).
|
||||||
|
Choose the first non-DST type
|
||||||
|
(or the first if they're all DST types). */
|
||||||
|
i = 0;
|
||||||
|
while (i < num_types && types[i].isdst)
|
||||||
|
{
|
||||||
|
if (__tzname[1] == NULL)
|
||||||
|
__tzname[1] = __tzstring (&zone_names[types[i].idx]);
|
||||||
|
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i == num_types)
|
||||||
|
i = 0;
|
||||||
|
__tzname[0] = __tzstring (&zone_names[types[i].idx]);
|
||||||
|
if (__tzname[1] == NULL)
|
||||||
|
{
|
||||||
|
size_t j = i;
|
||||||
|
while (j < num_types)
|
||||||
|
if (types[j].isdst)
|
||||||
|
{
|
||||||
|
__tzname[1] = __tzstring (&zone_names[types[j].idx]);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
++j;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (timer >= transitions[num_transitions - 1])
|
||||||
|
{
|
||||||
|
if (tzspec == NULL)
|
||||||
|
{
|
||||||
|
use_last:
|
||||||
|
i = num_transitions - 1;
|
||||||
|
goto found;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Parse the POSIX TZ-style string. */
|
||||||
|
__tzset_parse_tz (tzspec);
|
||||||
|
|
||||||
|
/* Convert to broken down structure. If this fails do not
|
||||||
|
use the string. */
|
||||||
|
if (! __offtime (&timer, 0, tp))
|
||||||
|
goto use_last;
|
||||||
|
|
||||||
|
/* Use the rules from the TZ string to compute the change. */
|
||||||
|
__tz_compute (timer, tp, 1);
|
||||||
|
|
||||||
|
*leap_correct = 0L;
|
||||||
|
*leap_hit = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Find the first transition after TIMER, and
|
||||||
|
then pick the type of the transition before it. */
|
||||||
|
size_t lo = 0;
|
||||||
|
size_t hi = num_transitions - 1;
|
||||||
|
/* Assume that DST is changing twice a year and guess initial
|
||||||
|
search spot from it.
|
||||||
|
Half of a gregorian year has on average 365.2425 * 86400 / 2
|
||||||
|
= 15778476 seconds. */
|
||||||
|
i = (transitions[num_transitions - 1] - timer) / 15778476;
|
||||||
|
if (i < num_transitions)
|
||||||
|
{
|
||||||
|
i = num_transitions - 1 - i;
|
||||||
|
if (timer < transitions[i])
|
||||||
|
{
|
||||||
|
if (i < 10 || timer >= transitions[i - 10])
|
||||||
|
{
|
||||||
|
/* Linear search. */
|
||||||
|
while (timer < transitions[i - 1])
|
||||||
|
--i;
|
||||||
|
goto found;
|
||||||
|
}
|
||||||
|
hi = i - 10;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (i + 10 >= num_transitions || timer < transitions[i + 10])
|
||||||
|
{
|
||||||
|
/* Linear search. */
|
||||||
|
while (timer >= transitions[i])
|
||||||
|
++i;
|
||||||
|
goto found;
|
||||||
|
}
|
||||||
|
lo = i + 10;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Binary search. */
|
||||||
|
/* assert (timer >= transitions[lo] && timer < transitions[hi]); */
|
||||||
|
while (lo + 1 < hi)
|
||||||
|
{
|
||||||
|
i = (lo + hi) / 2;
|
||||||
|
if (timer < transitions[i])
|
||||||
|
hi = i;
|
||||||
|
else
|
||||||
|
lo = i;
|
||||||
|
}
|
||||||
|
i = hi;
|
||||||
|
|
||||||
|
found:
|
||||||
|
/* assert (timer >= transitions[i - 1] && timer < transitions[i]); */
|
||||||
|
__tzname[types[type_idxs[i - 1]].isdst]
|
||||||
|
= __tzstring (&zone_names[types[type_idxs[i - 1]].idx]);
|
||||||
|
size_t j = i;
|
||||||
|
while (j < num_transitions)
|
||||||
|
{
|
||||||
|
int type = type_idxs[j];
|
||||||
|
int dst = types[type].isdst;
|
||||||
|
int idx = types[type].idx;
|
||||||
|
|
||||||
|
if (__tzname[dst] == NULL)
|
||||||
|
{
|
||||||
|
__tzname[dst] = __tzstring (&zone_names[idx]);
|
||||||
|
|
||||||
|
if (__tzname[1 - dst] != NULL)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
++j;
|
||||||
|
}
|
||||||
|
|
||||||
|
i = type_idxs[i - 1];
|
||||||
|
}
|
||||||
|
|
||||||
|
struct ttinfo *info = &types[i];
|
||||||
__daylight = rule_stdoff != rule_dstoff;
|
__daylight = rule_stdoff != rule_dstoff;
|
||||||
__timezone = -rule_stdoff;
|
__timezone = -rule_stdoff;
|
||||||
|
|
||||||
|
230
time/tzset.c
230
time/tzset.c
@ -1,4 +1,4 @@
|
|||||||
/* Copyright (C) 1991-2002,2003,2004 Free Software Foundation, Inc.
|
/* Copyright (C) 1991-2002,2003,2004,2007 Free Software Foundation, Inc.
|
||||||
This file is part of the GNU C Library.
|
This file is part of the GNU C Library.
|
||||||
|
|
||||||
The GNU C Library is free software; you can redistribute it and/or
|
The GNU C Library is free software; you can redistribute it and/or
|
||||||
@ -70,7 +70,6 @@ static tz_rule tz_rules[2];
|
|||||||
|
|
||||||
|
|
||||||
static void compute_change (tz_rule *rule, int year) __THROW internal_function;
|
static void compute_change (tz_rule *rule, int year) __THROW internal_function;
|
||||||
static void tz_compute (const struct tm *tm) __THROW internal_function;
|
|
||||||
static void tzset_internal (int always, int explicit)
|
static void tzset_internal (int always, int explicit)
|
||||||
__THROW internal_function;
|
__THROW internal_function;
|
||||||
|
|
||||||
@ -92,7 +91,7 @@ __tzstring (const char *s)
|
|||||||
{
|
{
|
||||||
char *p;
|
char *p;
|
||||||
struct tzstring_l *t, *u, *new;
|
struct tzstring_l *t, *u, *new;
|
||||||
size_t len = strlen(s);
|
size_t len = strlen (s);
|
||||||
|
|
||||||
/* Walk the list and look for a match. If this string is the same
|
/* Walk the list and look for a match. If this string is the same
|
||||||
as the end of an already-allocated string, it can share space. */
|
as the end of an already-allocated string, it can share space. */
|
||||||
@ -140,80 +139,34 @@ __tzname_max ()
|
|||||||
|
|
||||||
static char *old_tz;
|
static char *old_tz;
|
||||||
|
|
||||||
/* Interpret the TZ envariable. */
|
|
||||||
static void
|
static void
|
||||||
internal_function
|
internal_function
|
||||||
tzset_internal (always, explicit)
|
update_vars (void)
|
||||||
int always;
|
{
|
||||||
int explicit;
|
__daylight = tz_rules[0].offset != tz_rules[1].offset;
|
||||||
|
__timezone = -tz_rules[0].offset;
|
||||||
|
__tzname[0] = (char *) tz_rules[0].name;
|
||||||
|
__tzname[1] = (char *) tz_rules[1].name;
|
||||||
|
|
||||||
|
/* Keep __tzname_cur_max up to date. */
|
||||||
|
size_t len0 = strlen (__tzname[0]);
|
||||||
|
size_t len1 = strlen (__tzname[1]);
|
||||||
|
if (len0 > __tzname_cur_max)
|
||||||
|
__tzname_cur_max = len0;
|
||||||
|
if (len1 > __tzname_cur_max)
|
||||||
|
__tzname_cur_max = len1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Parse the POSIX TZ-style string. */
|
||||||
|
void
|
||||||
|
__tzset_parse_tz (tz)
|
||||||
|
const char *tz;
|
||||||
{
|
{
|
||||||
static int is_initialized;
|
|
||||||
register const char *tz;
|
|
||||||
register size_t l;
|
register size_t l;
|
||||||
char *tzbuf;
|
char *tzbuf;
|
||||||
unsigned short int hh, mm, ss;
|
unsigned short int hh, mm, ss;
|
||||||
unsigned short int whichrule;
|
unsigned short int whichrule;
|
||||||
|
|
||||||
if (is_initialized && !always)
|
|
||||||
return;
|
|
||||||
is_initialized = 1;
|
|
||||||
|
|
||||||
/* Examine the TZ environment variable. */
|
|
||||||
tz = getenv ("TZ");
|
|
||||||
if (tz == NULL && !explicit)
|
|
||||||
/* Use the site-wide default. This is a file name which means we
|
|
||||||
would not see changes to the file if we compare only the file
|
|
||||||
name for change. We want to notice file changes if tzset() has
|
|
||||||
been called explicitly. Leave TZ as NULL in this case. */
|
|
||||||
tz = TZDEFAULT;
|
|
||||||
if (tz && *tz == '\0')
|
|
||||||
/* User specified the empty string; use UTC explicitly. */
|
|
||||||
tz = "Universal";
|
|
||||||
|
|
||||||
/* A leading colon means "implementation defined syntax".
|
|
||||||
We ignore the colon and always use the same algorithm:
|
|
||||||
try a data file, and if none exists parse the 1003.1 syntax. */
|
|
||||||
if (tz && *tz == ':')
|
|
||||||
++tz;
|
|
||||||
|
|
||||||
/* Check whether the value changes since the last run. */
|
|
||||||
if (old_tz != NULL && tz != NULL && strcmp (tz, old_tz) == 0)
|
|
||||||
/* No change, simply return. */
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (tz == NULL)
|
|
||||||
/* No user specification; use the site-wide default. */
|
|
||||||
tz = TZDEFAULT;
|
|
||||||
|
|
||||||
tz_rules[0].name = NULL;
|
|
||||||
tz_rules[1].name = NULL;
|
|
||||||
|
|
||||||
/* Save the value of `tz'. */
|
|
||||||
if (old_tz != NULL)
|
|
||||||
free (old_tz);
|
|
||||||
old_tz = tz ? __strdup (tz) : NULL;
|
|
||||||
|
|
||||||
/* Try to read a data file. */
|
|
||||||
__tzfile_read (tz, 0, NULL);
|
|
||||||
if (__use_tzfile)
|
|
||||||
return;
|
|
||||||
|
|
||||||
/* No data file found. Default to UTC if nothing specified. */
|
|
||||||
|
|
||||||
if (tz == NULL || *tz == '\0'
|
|
||||||
|| (TZDEFAULT != NULL && strcmp (tz, TZDEFAULT) == 0))
|
|
||||||
{
|
|
||||||
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;
|
|
||||||
tz_rules[0].secs = tz_rules[1].secs = 0;
|
|
||||||
tz_rules[0].offset = tz_rules[1].offset = 0L;
|
|
||||||
tz_rules[0].change = tz_rules[1].change = (time_t) -1;
|
|
||||||
tz_rules[0].computed_for = tz_rules[1].computed_for = 0;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Clear out old state and reset to unnamed UTC. */
|
/* Clear out old state and reset to unnamed UTC. */
|
||||||
memset (tz_rules, 0, sizeof tz_rules);
|
memset (tz_rules, 0, sizeof tz_rules);
|
||||||
tz_rules[0].name = tz_rules[1].name = "";
|
tz_rules[0].name = tz_rules[1].name = "";
|
||||||
@ -413,20 +366,81 @@ tzset_internal (always, explicit)
|
|||||||
}
|
}
|
||||||
|
|
||||||
out:
|
out:
|
||||||
__daylight = tz_rules[0].offset != tz_rules[1].offset;
|
update_vars ();
|
||||||
__timezone = -tz_rules[0].offset;
|
}
|
||||||
__tzname[0] = (char *) tz_rules[0].name;
|
|
||||||
__tzname[1] = (char *) tz_rules[1].name;
|
|
||||||
|
|
||||||
{
|
/* Interpret the TZ envariable. */
|
||||||
/* Keep __tzname_cur_max up to date. */
|
static void
|
||||||
size_t len0 = strlen (__tzname[0]);
|
internal_function
|
||||||
size_t len1 = strlen (__tzname[1]);
|
tzset_internal (always, explicit)
|
||||||
if (len0 > __tzname_cur_max)
|
int always;
|
||||||
__tzname_cur_max = len0;
|
int explicit;
|
||||||
if (len1 > __tzname_cur_max)
|
{
|
||||||
__tzname_cur_max = len1;
|
static int is_initialized;
|
||||||
}
|
register const char *tz;
|
||||||
|
|
||||||
|
if (is_initialized && !always)
|
||||||
|
return;
|
||||||
|
is_initialized = 1;
|
||||||
|
|
||||||
|
/* Examine the TZ environment variable. */
|
||||||
|
tz = getenv ("TZ");
|
||||||
|
if (tz == NULL && !explicit)
|
||||||
|
/* Use the site-wide default. This is a file name which means we
|
||||||
|
would not see changes to the file if we compare only the file
|
||||||
|
name for change. We want to notice file changes if tzset() has
|
||||||
|
been called explicitly. Leave TZ as NULL in this case. */
|
||||||
|
tz = TZDEFAULT;
|
||||||
|
if (tz && *tz == '\0')
|
||||||
|
/* User specified the empty string; use UTC explicitly. */
|
||||||
|
tz = "Universal";
|
||||||
|
|
||||||
|
/* A leading colon means "implementation defined syntax".
|
||||||
|
We ignore the colon and always use the same algorithm:
|
||||||
|
try a data file, and if none exists parse the 1003.1 syntax. */
|
||||||
|
if (tz && *tz == ':')
|
||||||
|
++tz;
|
||||||
|
|
||||||
|
/* Check whether the value changes since the last run. */
|
||||||
|
if (old_tz != NULL && tz != NULL && strcmp (tz, old_tz) == 0)
|
||||||
|
/* No change, simply return. */
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (tz == NULL)
|
||||||
|
/* No user specification; use the site-wide default. */
|
||||||
|
tz = TZDEFAULT;
|
||||||
|
|
||||||
|
tz_rules[0].name = NULL;
|
||||||
|
tz_rules[1].name = NULL;
|
||||||
|
|
||||||
|
/* Save the value of `tz'. */
|
||||||
|
if (old_tz != NULL)
|
||||||
|
free (old_tz);
|
||||||
|
old_tz = tz ? __strdup (tz) : NULL;
|
||||||
|
|
||||||
|
/* Try to read a data file. */
|
||||||
|
__tzfile_read (tz, 0, NULL);
|
||||||
|
if (__use_tzfile)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* No data file found. Default to UTC if nothing specified. */
|
||||||
|
|
||||||
|
if (tz == NULL || *tz == '\0'
|
||||||
|
|| (TZDEFAULT != NULL && strcmp (tz, TZDEFAULT) == 0))
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
tz_rules[0].secs = tz_rules[1].secs = 0;
|
||||||
|
tz_rules[0].offset = tz_rules[1].offset = 0L;
|
||||||
|
tz_rules[0].change = tz_rules[1].change = (time_t) -1;
|
||||||
|
tz_rules[0].computed_for = tz_rules[1].computed_for = 0;
|
||||||
|
update_vars ();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
__tzset_parse_tz (tz);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Figure out the exact time (as a time_t) in YEAR
|
/* Figure out the exact time (as a time_t) in YEAR
|
||||||
@ -523,13 +537,34 @@ compute_change (rule, year)
|
|||||||
|
|
||||||
/* Figure out the correct timezone for TM and set `__tzname',
|
/* Figure out the correct timezone for TM and set `__tzname',
|
||||||
`__timezone', and `__daylight' accordingly. */
|
`__timezone', and `__daylight' accordingly. */
|
||||||
static void
|
void
|
||||||
internal_function
|
internal_function
|
||||||
tz_compute (tm)
|
__tz_compute (timer, tm, use_localtime)
|
||||||
const struct tm *tm;
|
time_t timer;
|
||||||
|
struct tm *tm;
|
||||||
|
int use_localtime;
|
||||||
{
|
{
|
||||||
compute_change (&tz_rules[0], 1900 + tm->tm_year);
|
compute_change (&tz_rules[0], 1900 + tm->tm_year);
|
||||||
compute_change (&tz_rules[1], 1900 + tm->tm_year);
|
compute_change (&tz_rules[1], 1900 + tm->tm_year);
|
||||||
|
|
||||||
|
if (use_localtime)
|
||||||
|
{
|
||||||
|
int isdst;
|
||||||
|
|
||||||
|
/* We have to distinguish between northern and southern
|
||||||
|
hemisphere. For the latter the daylight saving time
|
||||||
|
ends in the next year. */
|
||||||
|
if (__builtin_expect (tz_rules[0].change
|
||||||
|
> tz_rules[1].change, 0))
|
||||||
|
isdst = (timer < tz_rules[1].change
|
||||||
|
|| timer >= tz_rules[0].change);
|
||||||
|
else
|
||||||
|
isdst = (timer >= tz_rules[0].change
|
||||||
|
&& timer < tz_rules[1].change);
|
||||||
|
tm->tm_isdst = isdst;
|
||||||
|
tm->tm_zone = __tzname[isdst];
|
||||||
|
tm->tm_gmtoff = tz_rules[isdst].offset;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Reinterpret the TZ environment variable and set `tzname'. */
|
/* Reinterpret the TZ environment variable and set `tzname'. */
|
||||||
@ -583,35 +618,14 @@ __tz_convert (const time_t *timer, int use_localtime, struct tm *tp)
|
|||||||
if (! __offtime (timer, 0, tp))
|
if (! __offtime (timer, 0, tp))
|
||||||
tp = NULL;
|
tp = NULL;
|
||||||
else
|
else
|
||||||
tz_compute (tp);
|
__tz_compute (*timer, tp, use_localtime);
|
||||||
leap_correction = 0L;
|
leap_correction = 0L;
|
||||||
leap_extra_secs = 0;
|
leap_extra_secs = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tp)
|
if (tp)
|
||||||
{
|
{
|
||||||
if (use_localtime)
|
if (! use_localtime)
|
||||||
{
|
|
||||||
if (!__use_tzfile)
|
|
||||||
{
|
|
||||||
int isdst;
|
|
||||||
|
|
||||||
/* We have to distinguish between northern and southern
|
|
||||||
hemisphere. For the latter the daylight saving time
|
|
||||||
ends in the next year. */
|
|
||||||
if (__builtin_expect (tz_rules[0].change
|
|
||||||
> tz_rules[1].change, 0))
|
|
||||||
isdst = (*timer < tz_rules[1].change
|
|
||||||
|| *timer >= tz_rules[0].change);
|
|
||||||
else
|
|
||||||
isdst = (*timer >= tz_rules[0].change
|
|
||||||
&& *timer < tz_rules[1].change);
|
|
||||||
tp->tm_isdst = isdst;
|
|
||||||
tp->tm_zone = __tzname[isdst];
|
|
||||||
tp->tm_gmtoff = tz_rules[isdst].offset;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
tp->tm_isdst = 0;
|
tp->tm_isdst = 0;
|
||||||
tp->tm_zone = "GMT";
|
tp->tm_zone = "GMT";
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* Copyright (C) 1998, 1999, 2000, 2005 Free Software Foundation, Inc.
|
/* Copyright (C) 1998, 1999, 2000, 2005, 2007 Free Software Foundation, Inc.
|
||||||
This file is part of the GNU C Library.
|
This file is part of the GNU C Library.
|
||||||
Contributed by Andreas Jaeger <aj@suse.de>, 1998.
|
Contributed by Andreas Jaeger <aj@suse.de>, 1998.
|
||||||
|
|
||||||
@ -44,7 +44,6 @@ static const struct test_times tests[] =
|
|||||||
{ "America/Chicago", 1, 21600, {"CST", "CDT" }},
|
{ "America/Chicago", 1, 21600, {"CST", "CDT" }},
|
||||||
{ "America/Indiana/Indianapolis", 1, 18000, {"EST", "EDT" }},
|
{ "America/Indiana/Indianapolis", 1, 18000, {"EST", "EDT" }},
|
||||||
{ "America/Los_Angeles", 1, 28800, {"PST", "PDT" }},
|
{ "America/Los_Angeles", 1, 28800, {"PST", "PDT" }},
|
||||||
{ "Asia/Tokyo", 1, -32400, {"JST", "JDT" }},
|
|
||||||
{ "Pacific/Auckland", 1, -43200, { "NZST", "NZDT" }},
|
{ "Pacific/Auckland", 1, -43200, { "NZST", "NZDT" }},
|
||||||
{ NULL, 0, 0 }
|
{ NULL, 0, 0 }
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user