1
0
mirror of https://sourceware.org/git/glibc.git synced 2025-08-08 17:42:12 +03:00
This commit is contained in:
Jakub Jelinek
2007-07-31 13:33:18 +00:00
parent d6220e9ee3
commit 32c075e1f0
448 changed files with 13841 additions and 10982 deletions

View File

@@ -1,5 +1,4 @@
/* Copyright (C) 1991-1993,1995-2001,2003,2004,2006
Free Software Foundation, Inc.
/* Copyright (C) 1991-1993,1995-2001,2003,2004 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
@@ -72,34 +71,24 @@ static inline int
__attribute ((always_inline))
decode (const void *ptr)
{
if (BYTE_ORDER == BIG_ENDIAN && sizeof (int) == 4)
if ((BYTE_ORDER == BIG_ENDIAN) && sizeof (int) == 4)
return *(const int *) ptr;
if (sizeof (int) == 4)
else if (BYTE_ORDER == LITTLE_ENDIAN && sizeof (int) == 4)
return bswap_32 (*(const int *) ptr);
else
{
const unsigned char *p = ptr;
int result = *p & (1 << (CHAR_BIT - 1)) ? ~0 : 0;
const unsigned char *p = ptr;
int result = *p & (1 << (CHAR_BIT - 1)) ? ~0 : 0;
result = (result << 8) | *p++;
result = (result << 8) | *p++;
result = (result << 8) | *p++;
result = (result << 8) | *p++;
result = (result << 8) | *p++;
result = (result << 8) | *p++;
result = (result << 8) | *p++;
result = (result << 8) | *p++;
return result;
return result;
}
}
static inline int64_t
__attribute ((always_inline))
decode64 (const void *ptr)
{
if ((BYTE_ORDER == BIG_ENDIAN))
return *(const int64_t *) ptr;
return bswap_64 (*(const int64_t *) ptr);
}
void
__tzfile_read (const char *file, size_t extra, char **extrap)
{
@@ -113,10 +102,6 @@ __tzfile_read (const char *file, size_t extra, char **extrap)
size_t types_idx;
size_t leaps_idx;
int was_using_tzfile = __use_tzfile;
int trans_width = 4;
if (sizeof (time_t) != 4 && sizeof (time_t) != 8)
abort ();
__use_tzfile = 0;
@@ -200,10 +185,8 @@ __tzfile_read (const char *file, size_t extra, char **extrap)
/* No threads reading this stream. */
__fsetlocking (f, FSETLOCKING_BYCALLER);
read_again:
if (__builtin_expect (fread_unlocked ((void *) &tzhead, sizeof (tzhead),
1, f) != 1, 0)
|| memcmp (tzhead.tzh_magic, TZ_MAGIC, sizeof (tzhead.tzh_magic)) != 0)
1, f) != 1, 0))
goto lose;
num_transitions = (size_t) decode (tzhead.tzh_timecnt);
@@ -213,26 +196,6 @@ __tzfile_read (const char *file, size_t extra, char **extrap)
num_isstd = (size_t) decode (tzhead.tzh_ttisstdcnt);
num_isgmt = (size_t) decode (tzhead.tzh_ttisgmtcnt);
/* For platforms with 64-bit time_t we use the new format if available. */
if (sizeof (time_t) == 8 && trans_width == 4
&& tzhead.tzh_version[0] != '\0')
{
/* We use the 8-byte format. */
trans_width = 8;
/* Position the stream before the second header. */
size_t to_skip = (num_transitions * (4 + 1)
+ num_types * 6
+ chars
+ num_leaps * 8
+ num_isstd
+ num_isgmt);
if (fseek (f, to_skip, SEEK_CUR) != 0)
goto lose;
goto read_again;
}
total_size = num_transitions * (sizeof (time_t) + 1);
total_size = ((total_size + __alignof__ (struct ttinfo) - 1)
& ~(__alignof__ (struct ttinfo) - 1));
@@ -242,10 +205,10 @@ __tzfile_read (const char *file, size_t extra, char **extrap)
& ~(__alignof__ (struct leap) - 1));
leaps_idx = total_size;
total_size += num_leaps * sizeof (struct leap);
/* This is for the extra memory required by the caller. */
total_size += extra;
/* Allocate enough memory including the extra block requested by the
caller. */
transitions = (time_t *) malloc (total_size + extra);
transitions = (time_t *) malloc (total_size);
if (transitions == NULL)
goto lose;
@@ -257,11 +220,14 @@ __tzfile_read (const char *file, size_t extra, char **extrap)
if (extra > 0)
*extrap = (char *) &leaps[num_leaps];
if (sizeof (time_t) == 4 || trans_width == 8)
if (sizeof (time_t) < 4)
abort ();
if (sizeof (time_t) == 4)
{
if (__builtin_expect (fread_unlocked (transitions, trans_width + 1,
num_transitions, f)
!= num_transitions, 0))
if (__builtin_expect (fread_unlocked (transitions, 1,
(4 + 1) * num_transitions, f)
!= (4 + 1) * num_transitions, 0))
goto lose;
}
else
@@ -279,9 +245,7 @@ __tzfile_read (const char *file, size_t extra, char **extrap)
if (__builtin_expect (type_idxs[i] >= num_types, 0))
goto lose;
if ((BYTE_ORDER != BIG_ENDIAN && (sizeof (time_t) == 4 || trans_width == 4))
|| (BYTE_ORDER == BIG_ENDIAN && sizeof (time_t) == 8
&& trans_width == 4))
if (BYTE_ORDER != BIG_ENDIAN || sizeof (time_t) != 4)
{
/* Decode the transition times, stored as 4-byte integers in
network (big-endian) byte order. We work from the end of
@@ -291,13 +255,6 @@ __tzfile_read (const char *file, size_t extra, char **extrap)
while (i-- > 0)
transitions[i] = decode ((char *) transitions + i * 4);
}
else if (BYTE_ORDER != BIG_ENDIAN && sizeof (time_t) == 8)
{
/* Decode the transition times, stored as 8-byte integers in
network (big-endian) byte order. */
for (i = 0; i < num_transitions; ++i)
transitions[i] = decode64 ((char *) transitions + i * 8);
}
for (i = 0; i < num_types; ++i)
{
@@ -323,16 +280,13 @@ __tzfile_read (const char *file, size_t extra, char **extrap)
for (i = 0; i < num_leaps; ++i)
{
unsigned char x[8];
if (__builtin_expect (fread_unlocked (x, 1, trans_width, f)
!= trans_width, 0))
unsigned char x[4];
if (__builtin_expect (fread_unlocked (x, 1, sizeof (x), f) != sizeof (x),
0))
goto lose;
if (sizeof (time_t) == 4 || trans_width == 4)
leaps[i].transition = (time_t) decode (x);
else
leaps[i].transition = (time_t) decode64 (x);
if (__builtin_expect (fread_unlocked (x, 1, 4, f) != 4, 0))
leaps[i].transition = (time_t) decode (x);
if (__builtin_expect (fread_unlocked (x, 1, sizeof (x), f) != sizeof (x),
0))
goto lose;
leaps[i].change = (long int) decode (x);
}
@@ -357,12 +311,6 @@ __tzfile_read (const char *file, size_t extra, char **extrap)
while (i < num_types)
types[i++].isgmt = 0;
/* XXX When a version 2 file is available it can contain a POSIX TZ-style
formatted string which specifies how times past the last one specified
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
open-ended last entry. */
fclose (f);
/* First "register" all timezone names. */