/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; |
} |