Subversion Repositories Kolibri OS

Compare Revisions

Regard whitespace Rev 4921 → Rev 6099

/contrib/sdk/sources/newlib/libc/time/mktm_r.c
File deleted
/contrib/sdk/sources/newlib/libc/time/clock.c
59,7 → 59,7
struct tms tim_s;
clock_t res;
 
if ((res = (clock_t) _times_r (_REENT, &tim_s)) != -1)
if ((res = (clock_t) _times_r (_REENT, &tim_s)) != (clock_t) -1)
res = (clock_t) (tim_s.tms_utime + tim_s.tms_stime +
tim_s.tms_cutime + tim_s.tms_cstime);
 
/contrib/sdk/sources/newlib/libc/time/gmtime_r.c
1,14 → 1,101
/*
* gmtime_r.c
* Original Author: Adapted from tzcode maintained by Arthur David Olson.
* Modifications:
* - Changed to mktm_r and added __tzcalc_limits - 04/10/02, Jeff Johnston
* - Fixed bug in mday computations - 08/12/04, Alex Mogilnikov <alx@intellectronika.ru>
* - Fixed bug in __tzcalc_limits - 08/12/04, Alex Mogilnikov <alx@intellectronika.ru>
* - Move code from _mktm_r() to gmtime_r() - 05/09/14, Freddie Chopin <freddie_chopin@op.pl>
* - Fixed bug in calculations for dates after year 2069 or before year 1901. Ideas for
* solution taken from musl's __secs_to_tm() - 07/12/2014, Freddie Chopin
* <freddie_chopin@op.pl>
* - Use faster algorithm from civil_from_days() by Howard Hinnant - 12/06/2014,
* Freddie Chopin <freddie_chopin@op.pl>
*
* Converts the calendar time pointed to by tim_p into a broken-down time
* expressed as local time. Returns a pointer to a structure containing the
* broken-down time.
*/
 
#include <time.h>
#include "local.h"
 
/* Move epoch from 01.01.1970 to 01.03.0000 (yes, Year 0) - this is the first
* day of a 400-year long "era", right after additional day of leap year.
* This adjustment is required only for date calculation, so instead of
* modifying time_t value (which would require 64-bit operations to work
* correctly) it's enough to adjust the calculated number of days since epoch.
*/
#define EPOCH_ADJUSTMENT_DAYS 719468L
/* year to which the adjustment was made */
#define ADJUSTED_EPOCH_YEAR 0
/* 1st March of year 0 is Wednesday */
#define ADJUSTED_EPOCH_WDAY 3
/* there are 97 leap years in 400-year periods. ((400 - 97) * 365 + 97 * 366) */
#define DAYS_PER_ERA 146097L
/* there are 24 leap years in 100-year periods. ((100 - 24) * 365 + 24 * 366) */
#define DAYS_PER_CENTURY 36524L
/* there is one leap year every 4 years */
#define DAYS_PER_4_YEARS (3 * 365 + 366)
/* number of days in a non-leap year */
#define DAYS_PER_YEAR 365
/* number of days in January */
#define DAYS_IN_JANUARY 31
/* number of days in non-leap February */
#define DAYS_IN_FEBRUARY 28
/* number of years per era */
#define YEARS_PER_ERA 400
 
struct tm *
_DEFUN (gmtime_r, (tim_p, res),
_CONST time_t *__restrict tim_p _AND
struct tm *__restrict res)
{
return (_mktm_r (tim_p, res, 1));
long days, rem;
_CONST time_t lcltime = *tim_p;
int era, weekday, year;
unsigned erayear, yearday, month, day;
unsigned long eraday;
 
days = ((long)lcltime) / SECSPERDAY + EPOCH_ADJUSTMENT_DAYS;
rem = ((long)lcltime) % SECSPERDAY;
if (rem < 0)
{
rem += SECSPERDAY;
--days;
}
 
/* compute hour, min, and sec */
res->tm_hour = (int) (rem / SECSPERHOUR);
rem %= SECSPERHOUR;
res->tm_min = (int) (rem / SECSPERMIN);
res->tm_sec = (int) (rem % SECSPERMIN);
 
/* compute day of week */
if ((weekday = ((ADJUSTED_EPOCH_WDAY + days) % DAYSPERWEEK)) < 0)
weekday += DAYSPERWEEK;
res->tm_wday = weekday;
 
/* compute year, month, day & day of year */
/* for description of this algorithm see
* http://howardhinnant.github.io/date_algorithms.html#civil_from_days */
era = (days >= 0 ? days : days - (DAYS_PER_ERA - 1)) / DAYS_PER_ERA;
eraday = days - era * DAYS_PER_ERA; /* [0, 146096] */
erayear = (eraday - eraday / (DAYS_PER_4_YEARS - 1) + eraday / DAYS_PER_CENTURY -
eraday / (DAYS_PER_ERA - 1)) / 365; /* [0, 399] */
yearday = eraday - (DAYS_PER_YEAR * erayear + erayear / 4 - erayear / 100); /* [0, 365] */
month = (5 * yearday + 2) / 153; /* [0, 11] */
day = yearday - (153 * month + 2) / 5 + 1; /* [1, 31] */
month += month < 10 ? 2 : -10;
year = ADJUSTED_EPOCH_YEAR + erayear + era * YEARS_PER_ERA + (month <= 1);
 
res->tm_yday = yearday >= DAYS_PER_YEAR - DAYS_IN_JANUARY - DAYS_IN_FEBRUARY ?
yearday - (DAYS_PER_YEAR - DAYS_IN_JANUARY - DAYS_IN_FEBRUARY) :
yearday + DAYS_IN_JANUARY + DAYS_IN_FEBRUARY + isleap(erayear);
res->tm_year = year - YEAR_BASE;
res->tm_mon = month;
res->tm_mday = day;
 
res->tm_isdst = 0;
 
return (res);
}
/contrib/sdk/sources/newlib/libc/time/lcltime_r.c
1,5 → 1,12
/*
* localtime_r.c
* Original Author: Adapted from tzcode maintained by Arthur David Olson.
* Modifications:
* - Changed to mktm_r and added __tzcalc_limits - 04/10/02, Jeff Johnston
* - Fixed bug in mday computations - 08/12/04, Alex Mogilnikov <alx@intellectronika.ru>
* - Fixed bug in __tzcalc_limits - 08/12/04, Alex Mogilnikov <alx@intellectronika.ru>
* - Implement localtime_r() with gmtime_r() and the conditional code moved
* from _mktm_r() - 05/09/14, Freddie Chopin <freddie_chopin@op.pl>
*
* Converts the calendar time pointed to by tim_p into a broken-down time
* expressed as local time. Returns a pointer to a structure containing the
6,7 → 13,6
* broken-down time.
*/
 
#include <time.h>
#include "local.h"
 
struct tm *
14,5 → 20,108
_CONST time_t *__restrict tim_p _AND
struct tm *__restrict res)
{
return _mktm_r (tim_p, res, 0);
long offset;
int hours, mins, secs;
int year;
__tzinfo_type *_CONST tz = __gettzinfo ();
_CONST int *ip;
 
res = gmtime_r (tim_p, res);
 
year = res->tm_year + YEAR_BASE;
ip = __month_lengths[isleap(year)];
 
TZ_LOCK;
_tzset_unlocked ();
if (_daylight)
{
if (year == tz->__tzyear || __tzcalc_limits (year))
res->tm_isdst = (tz->__tznorth
? (*tim_p >= tz->__tzrule[0].change
&& *tim_p < tz->__tzrule[1].change)
: (*tim_p >= tz->__tzrule[0].change
|| *tim_p < tz->__tzrule[1].change));
else
res->tm_isdst = -1;
}
else
res->tm_isdst = 0;
 
offset = (res->tm_isdst == 1
? tz->__tzrule[1].offset
: tz->__tzrule[0].offset);
 
hours = (int) (offset / SECSPERHOUR);
offset = offset % SECSPERHOUR;
 
mins = (int) (offset / SECSPERMIN);
secs = (int) (offset % SECSPERMIN);
 
res->tm_sec -= secs;
res->tm_min -= mins;
res->tm_hour -= hours;
 
if (res->tm_sec >= SECSPERMIN)
{
res->tm_min += 1;
res->tm_sec -= SECSPERMIN;
}
else if (res->tm_sec < 0)
{
res->tm_min -= 1;
res->tm_sec += SECSPERMIN;
}
if (res->tm_min >= MINSPERHOUR)
{
res->tm_hour += 1;
res->tm_min -= MINSPERHOUR;
}
else if (res->tm_min < 0)
{
res->tm_hour -= 1;
res->tm_min += MINSPERHOUR;
}
if (res->tm_hour >= HOURSPERDAY)
{
++res->tm_yday;
++res->tm_wday;
if (res->tm_wday > 6)
res->tm_wday = 0;
++res->tm_mday;
res->tm_hour -= HOURSPERDAY;
if (res->tm_mday > ip[res->tm_mon])
{
res->tm_mday -= ip[res->tm_mon];
res->tm_mon += 1;
if (res->tm_mon == 12)
{
res->tm_mon = 0;
res->tm_year += 1;
res->tm_yday = 0;
}
}
}
else if (res->tm_hour < 0)
{
res->tm_yday -= 1;
res->tm_wday -= 1;
if (res->tm_wday < 0)
res->tm_wday = 6;
res->tm_mday -= 1;
res->tm_hour += 24;
if (res->tm_mday == 0)
{
res->tm_mon -= 1;
if (res->tm_mon < 0)
{
res->tm_mon = 11;
res->tm_year -= 1;
res->tm_yday = 364 + isleap(res->tm_year + YEAR_BASE);
}
res->tm_mday = ip[res->tm_mon];
}
}
TZ_UNLOCK;
 
return (res);
}
/contrib/sdk/sources/newlib/libc/time/local.h
19,9 → 19,13
 
#define isleap(y) ((((y) % 4) == 0 && ((y) % 100) != 0) || ((y) % 400) == 0)
 
struct tm * _EXFUN (_mktm_r, (_CONST time_t *, struct tm *, int __is_gmtime));
int _EXFUN (__tzcalc_limits, (int __year));
 
extern _CONST int __month_lengths[2][MONSPERYEAR];
 
_VOID _EXFUN(_tzset_unlocked_r, (struct _reent *));
_VOID _EXFUN(_tzset_unlocked, (_VOID));
 
/* locks for multi-threading */
#ifdef __SINGLE_THREAD__
#define TZ_LOCK
/contrib/sdk/sources/newlib/libc/time/mktime.c
199,6 → 199,8
 
TZ_LOCK;
 
_tzset_unlocked ();
 
if (_daylight)
{
int tm_isdst;
/contrib/sdk/sources/newlib/libc/time/month_lengths.c
0,0 → 1,14
/*
* month_lengths.c
*
* Array __month_lengths[] is (indirectly) needed by tzset(), mktime(),
* gmtime() and localtime(). To break any dependencies, this array is moved to
* separate source file.
*/
 
#include "local.h"
 
_CONST int __month_lengths[2][MONSPERYEAR] = {
{31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
{31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}
} ;
/contrib/sdk/sources/newlib/libc/time/strftime.c
166,6 → 166,10
o %R
The 24-hour time, to the minute. Equivalent to "%H:%M". [tm_min, tm_hour]
 
o %s
The time elapsed, in seconds, since the start of the Unix epoch at
1970-01-01 00:00:00 UTC.
 
o %S
The second, formatted with two digits (from `<<00>>' to `<<60>>'). The
value 60 accounts for the occasional leap second. [tm_sec]
694,15 → 698,16
#endif /* !_WANT_C99_TIME_FORMATS */
{
size_t count = 0;
int i, len = 0;
int len = 0;
const CHAR *ctloc;
#if defined (MAKE_WCSFTIME) && !defined (__HAVE_LOCALE_INFO_EXTENDED__)
CHAR ctlocbuf[CTLOCBUFLEN];
#endif
size_t ctloclen;
size_t i, ctloclen;
CHAR alt;
CHAR pad;
unsigned long width;
int tzset_called = 0;
 
struct lc_time_T *_CurrentTimeLocale = __get_current_time_locale ();
for (;;)
1108,6 → 1113,74
tim_p->tm_hour, tim_p->tm_min);
CHECK_LENGTH ();
break;
case CQ('s'):
/*
* From:
* The Open Group Base Specifications Issue 7
* IEEE Std 1003.1, 2013 Edition
* Copyright (c) 2001-2013 The IEEE and The Open Group
* XBD Base Definitions
* 4. General Concepts
* 4.15 Seconds Since the Epoch
* A value that approximates the number of seconds that have elapsed since the
* Epoch. A Coordinated Universal Time name (specified in terms of seconds
* (tm_sec), minutes (tm_min), hours (tm_hour), days since January 1 of the year
* (tm_yday), and calendar year minus 1900 (tm_year)) is related to a time
* represented as seconds since the Epoch, according to the expression below.
* If the year is <1970 or the value is negative, the relationship is undefined.
* If the year is >=1970 and the value is non-negative, the value is related to a
* Coordinated Universal Time name according to the C-language expression, where
* tm_sec, tm_min, tm_hour, tm_yday, and tm_year are all integer types:
* tm_sec + tm_min*60 + tm_hour*3600 + tm_yday*86400 +
* (tm_year-70)*31536000 + ((tm_year-69)/4)*86400 -
* ((tm_year-1)/100)*86400 + ((tm_year+299)/400)*86400
* OR
* ((((tm_year-69)/4 - (tm_year-1)/100 + (tm_year+299)/400 +
* (tm_year-70)*365 + tm_yday)*24 + tm_hour)*60 + tm_min)*60 + tm_sec
*/
/* modified from %z case by hoisting offset outside if block and initializing */
{
long offset = 0; /* offset < 0 => W of GMT, > 0 => E of GMT:
subtract to get UTC */
 
if (tim_p->tm_isdst >= 0)
{
TZ_LOCK;
if (!tzset_called)
{
_tzset_unlocked ();
tzset_called = 1;
}
 
#if defined (__CYGWIN__)
/* Cygwin must check if the application has been built with or
without the extra tm members for backward compatibility, and
then use either that or the old method fetching from tzinfo.
Rather than pulling in the version check infrastructure, we
just call a Cygwin function. */
extern long __cygwin_gettzoffset (const struct tm *tmp);
offset = __cygwin_gettzoffset (tim_p);
#elif defined (__TM_GMTOFF)
offset = tim_p->__TM_GMTOFF;
#else
__tzinfo_type *tz = __gettzinfo ();
/* The sign of this is exactly opposite the envvar TZ. We
could directly use the global _timezone for tm_isdst==0,
but have to use __tzrule for daylight savings. */
offset = -tz->__tzrule[tim_p->tm_isdst > 0].offset;
#endif
TZ_UNLOCK;
}
len = snprintf (&s[count], maxsize - count, CQ("%lld"),
(((((long long)tim_p->tm_year - 69)/4
- (tim_p->tm_year - 1)/100
+ (tim_p->tm_year + 299)/400
+ (tim_p->tm_year - 70)*365 + tim_p->tm_yday)*24
+ tim_p->tm_hour)*60 + tim_p->tm_min)*60
+ tim_p->tm_sec - offset);
CHECK_LENGTH ();
}
break;
case CQ('S'):
#ifdef _WANT_C99_TIME_FORMATS
if (alt != CQ('O') || !*alt_digits
1283,12 → 1356,31
if (tim_p->tm_isdst >= 0)
{
long offset;
 
TZ_LOCK;
if (!tzset_called)
{
_tzset_unlocked ();
tzset_called = 1;
}
 
#if defined (__CYGWIN__)
/* Cygwin must check if the application has been built with or
without the extra tm members for backward compatibility, and
then use either that or the old method fetching from tzinfo.
Rather than pulling in the version check infrastructure, we
just call a Cygwin function. */
extern long __cygwin_gettzoffset (const struct tm *tmp);
offset = __cygwin_gettzoffset (tim_p);
#elif defined (__TM_GMTOFF)
offset = tim_p->__TM_GMTOFF;
#else
__tzinfo_type *tz = __gettzinfo ();
TZ_LOCK;
/* The sign of this is exactly opposite the envvar TZ. We
could directly use the global _timezone for tm_isdst==0,
but have to use __tzrule for daylight savings. */
offset = -tz->__tzrule[tim_p->tm_isdst > 0].offset;
#endif
TZ_UNLOCK;
len = snprintf (&s[count], maxsize - count, CQ("%+03ld%.2ld"),
offset / SECSPERHOUR,
1299,13 → 1391,33
case CQ('Z'):
if (tim_p->tm_isdst >= 0)
{
int size;
size_t size;
const char *tznam = NULL;
 
TZ_LOCK;
size = strlen(_tzname[tim_p->tm_isdst > 0]);
if (!tzset_called)
{
_tzset_unlocked ();
tzset_called = 1;
}
#if defined (__CYGWIN__)
/* See above. */
extern const char *__cygwin_gettzname (const struct tm *tmp);
tznam = __cygwin_gettzname (tim_p);
#elif defined (__TM_ZONE)
tznam = tim_p->__TM_ZONE;
#endif
if (!tznam)
tznam = _tzname[tim_p->tm_isdst > 0];
/* Note that in case of wcsftime this loop only works for
timezone abbreviations using the portable codeset (aka ASCII).
This seems to be the case, but if that ever changes, this
loop needs revisiting. */
size = strlen (tznam);
for (i = 0; i < size; i++)
{
if (count < maxsize - 1)
s[count++] = _tzname[tim_p->tm_isdst > 0][i];
s[count++] = tznam[i];
else
{
TZ_UNLOCK;
1402,6 → 1514,7
{ CQ("%p"), 2+1, EXP(CQ("AM")) },
{ CQ("%r"), 11+1, EXP(CQ("09:53:47 AM")) },
{ CQ("%R"), 5+1, EXP(CQ("09:53")) },
{ CQ("%s"), 2+1, EXP(CQ("1230648827")) },
{ CQ("%S"), 2+1, EXP(CQ("47")) },
{ CQ("%t"), 1+1, EXP(CQ("\t")) },
{ CQ("%T"), 8+1, EXP(CQ("09:53:47")) },
1462,6 → 1575,7
{ CQ("%p"), 2+1, EXP(CQ("PM")) },
{ CQ("%r"), 11+1, EXP(CQ("11:01:13 PM")) },
{ CQ("%R"), 5+1, EXP(CQ("23:01")) },
{ CQ("%s"), 2+1, EXP(CQ("1215054073")) },
{ CQ("%S"), 2+1, EXP(CQ("13")) },
{ CQ("%t"), 1+1, EXP(CQ("\t")) },
{ CQ("%T"), 8+1, EXP(CQ("23:01:13")) },
/contrib/sdk/sources/newlib/libc/time/tzcalc_limits.c
0,0 → 1,77
/*
* tzcalc_limits.c
* Original Author: Adapted from tzcode maintained by Arthur David Olson.
* Modifications:
* - Changed to mktm_r and added __tzcalc_limits - 04/10/02, Jeff Johnston
* - Fixed bug in mday computations - 08/12/04, Alex Mogilnikov <alx@intellectronika.ru>
* - Fixed bug in __tzcalc_limits - 08/12/04, Alex Mogilnikov <alx@intellectronika.ru>
* - Moved __tzcalc_limits() to separate file - 05/09/14, Freddie Chopin <freddie_chopin@op.pl>
*/
 
#include "local.h"
 
int
_DEFUN (__tzcalc_limits, (year),
int year)
{
int days, year_days, years;
int i, j;
__tzinfo_type *_CONST tz = __gettzinfo ();
 
if (year < EPOCH_YEAR)
return 0;
 
tz->__tzyear = year;
 
years = (year - EPOCH_YEAR);
 
year_days = years * 365 +
(years - 1 + EPOCH_YEARS_SINCE_LEAP) / 4 -
(years - 1 + EPOCH_YEARS_SINCE_CENTURY) / 100 +
(years - 1 + EPOCH_YEARS_SINCE_LEAP_CENTURY) / 400;
 
for (i = 0; i < 2; ++i)
{
if (tz->__tzrule[i].ch == 'J')
{
/* The Julian day n (1 <= n <= 365). */
days = year_days + tz->__tzrule[i].d +
(isleap(year) && tz->__tzrule[i].d >= 60);
/* Convert to yday */
--days;
}
else if (tz->__tzrule[i].ch == 'D')
days = year_days + tz->__tzrule[i].d;
else
{
_CONST int yleap = isleap(year);
int m_day, m_wday, wday_diff;
_CONST int *_CONST ip = __month_lengths[yleap];
 
days = year_days;
 
for (j = 1; j < tz->__tzrule[i].m; ++j)
days += ip[j-1];
 
m_wday = (EPOCH_WDAY + days) % DAYSPERWEEK;
 
wday_diff = tz->__tzrule[i].d - m_wday;
if (wday_diff < 0)
wday_diff += DAYSPERWEEK;
m_day = (tz->__tzrule[i].n - 1) * DAYSPERWEEK + wday_diff;
 
while (m_day >= ip[j-1])
m_day -= DAYSPERWEEK;
 
days += m_day;
}
 
/* store the change-over time in GMT form by adding offset */
tz->__tzrule[i].change = days * SECSPERDAY +
tz->__tzrule[i].s + tz->__tzrule[i].offset;
}
 
tz->__tznorth = (tz->__tzrule[0].change < tz->__tzrule[1].change);
 
return 1;
}
/contrib/sdk/sources/newlib/libc/time/tzset.c
0,0 → 1,82
/*
FUNCTION
<<tzset>>---set timezone characteristics from TZ environment variable
 
INDEX
tzset
INDEX
_tzset_r
 
ANSI_SYNOPSIS
#include <time.h>
void tzset(void);
void _tzset_r (struct _reent *<[reent_ptr]>);
 
TRAD_SYNOPSIS
#include <time.h>
void tzset();
void _tzset_r (<[reent_ptr]>);
struct _reent *reent_ptr;
 
DESCRIPTION
<<tzset>> examines the TZ environment variable and sets up the three
external variables: <<_timezone>>, <<_daylight>>, and <<tzname>>. The
value of <<_timezone>> shall be the offset from the current time zone
to GMT. The value of <<_daylight>> shall be 0 if there is no daylight
savings time for the current time zone, otherwise it will be non-zero.
The <<tzname>> array has two entries: the first is the name of the
standard time zone, the second is the name of the daylight-savings time
zone.
 
The TZ environment variable is expected to be in the following POSIX
format:
 
stdoffset1[dst[offset2][,start[/time1],end[/time2]]]
 
where: std is the name of the standard time-zone (minimum 3 chars)
offset1 is the value to add to local time to arrive at Universal time
it has the form: hh[:mm[:ss]]
dst is the name of the alternate (daylight-savings) time-zone (min 3 chars)
offset2 is the value to add to local time to arrive at Universal time
it has the same format as the std offset
start is the day that the alternate time-zone starts
time1 is the optional time that the alternate time-zone starts
(this is in local time and defaults to 02:00:00 if not specified)
end is the day that the alternate time-zone ends
time2 is the time that the alternate time-zone ends
(it is in local time and defaults to 02:00:00 if not specified)
 
Note that there is no white-space padding between fields. Also note that
if TZ is null, the default is Universal GMT which has no daylight-savings
time. If TZ is empty, the default EST5EDT is used.
 
The function <<_tzset_r>> is identical to <<tzset>> only it is reentrant
and is used for applications that use multiple threads.
 
RETURNS
There is no return value.
 
PORTABILITY
<<tzset>> is part of the POSIX standard.
 
Supporting OS subroutine required: None
*/
 
#include <_ansi.h>
#include <reent.h>
#include <time.h>
#include "local.h"
 
_VOID
_DEFUN_VOID (_tzset_unlocked)
{
_tzset_unlocked_r (_REENT);
}
 
_VOID
_DEFUN_VOID (tzset)
{
TZ_LOCK;
_tzset_unlocked_r (_REENT);
TZ_UNLOCK;
}
/contrib/sdk/sources/newlib/libc/time/tzset_r.c
0,0 → 1,193
#include <_ansi.h>
#include <reent.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/time.h>
#include "local.h"
 
#define sscanf siscanf /* avoid to pull in FP functions. */
 
static char __tzname_std[11];
static char __tzname_dst[11];
static char *prev_tzenv = NULL;
 
_VOID
_DEFUN (_tzset_unlocked_r, (reent_ptr),
struct _reent *reent_ptr)
{
char *tzenv;
unsigned short hh, mm, ss, m, w, d;
int sign, n;
int i, ch;
__tzinfo_type *tz = __gettzinfo ();
 
if ((tzenv = _getenv_r (reent_ptr, "TZ")) == NULL)
{
_timezone = 0;
_daylight = 0;
_tzname[0] = "GMT";
_tzname[1] = "GMT";
free(prev_tzenv);
prev_tzenv = NULL;
return;
}
 
if (prev_tzenv != NULL && strcmp(tzenv, prev_tzenv) == 0)
return;
 
free(prev_tzenv);
prev_tzenv = _malloc_r (reent_ptr, strlen(tzenv) + 1);
if (prev_tzenv != NULL)
strcpy (prev_tzenv, tzenv);
 
/* ignore implementation-specific format specifier */
if (*tzenv == ':')
++tzenv;
 
if (sscanf (tzenv, "%10[^0-9,+-]%n", __tzname_std, &n) <= 0)
return;
tzenv += n;
 
sign = 1;
if (*tzenv == '-')
{
sign = -1;
++tzenv;
}
else if (*tzenv == '+')
++tzenv;
 
mm = 0;
ss = 0;
if (sscanf (tzenv, "%hu%n:%hu%n:%hu%n", &hh, &n, &mm, &n, &ss, &n) < 1)
return;
tz->__tzrule[0].offset = sign * (ss + SECSPERMIN * mm + SECSPERHOUR * hh);
_tzname[0] = __tzname_std;
tzenv += n;
if (sscanf (tzenv, "%10[^0-9,+-]%n", __tzname_dst, &n) <= 0)
{ /* No dst */
_tzname[1] = _tzname[0];
_timezone = tz->__tzrule[0].offset;
_daylight = 0;
return;
}
else
_tzname[1] = __tzname_dst;
 
tzenv += n;
 
/* otherwise we have a dst name, look for the offset */
sign = 1;
if (*tzenv == '-')
{
sign = -1;
++tzenv;
}
else if (*tzenv == '+')
++tzenv;
 
hh = 0;
mm = 0;
ss = 0;
n = 0;
if (sscanf (tzenv, "%hu%n:%hu%n:%hu%n", &hh, &n, &mm, &n, &ss, &n) <= 0)
tz->__tzrule[1].offset = tz->__tzrule[0].offset - 3600;
else
tz->__tzrule[1].offset = sign * (ss + SECSPERMIN * mm + SECSPERHOUR * hh);
 
tzenv += n;
 
for (i = 0; i < 2; ++i)
{
if (*tzenv == ',')
++tzenv;
 
if (*tzenv == 'M')
{
if (sscanf (tzenv, "M%hu%n.%hu%n.%hu%n", &m, &n, &w, &n, &d, &n) != 3 ||
m < 1 || m > 12 || w < 1 || w > 5 || d > 6)
return;
tz->__tzrule[i].ch = 'M';
tz->__tzrule[i].m = m;
tz->__tzrule[i].n = w;
tz->__tzrule[i].d = d;
tzenv += n;
}
else
{
char *end;
if (*tzenv == 'J')
{
ch = 'J';
++tzenv;
}
else
ch = 'D';
d = strtoul (tzenv, &end, 10);
/* if unspecified, default to US settings */
/* From 1987-2006, US was M4.1.0,M10.5.0, but starting in 2007 is
* M3.2.0,M11.1.0 (2nd Sunday March through 1st Sunday November) */
if (end == tzenv)
{
if (i == 0)
{
tz->__tzrule[0].ch = 'M';
tz->__tzrule[0].m = 3;
tz->__tzrule[0].n = 2;
tz->__tzrule[0].d = 0;
}
else
{
tz->__tzrule[1].ch = 'M';
tz->__tzrule[1].m = 11;
tz->__tzrule[1].n = 1;
tz->__tzrule[1].d = 0;
}
}
else
{
tz->__tzrule[i].ch = ch;
tz->__tzrule[i].d = d;
}
tzenv = end;
}
/* default time is 02:00:00 am */
hh = 2;
mm = 0;
ss = 0;
n = 0;
if (*tzenv == '/')
sscanf (tzenv, "/%hu%n:%hu%n:%hu%n", &hh, &n, &mm, &n, &ss, &n);
 
tz->__tzrule[i].s = ss + SECSPERMIN * mm + SECSPERHOUR * hh;
tzenv += n;
}
 
__tzcalc_limits (tz->__tzyear);
_timezone = tz->__tzrule[0].offset;
_daylight = tz->__tzrule[0].offset != tz->__tzrule[1].offset;
}
 
_VOID
_DEFUN (_tzset_r, (reent_ptr),
struct _reent *reent_ptr)
{
TZ_LOCK;
_tzset_unlocked_r (reent_ptr);
TZ_UNLOCK;
}