[PATCH] libc/time/gmtime_r.c, libc/time/lcltime_r.c,, libc/time/local.h, libc/time/mktm_r.c: move localtime related functionality, from _mktm_r() to new _mklocaltm_r() to break dependency of gmtime() on, timezones
Freddie Chopin
freddie_chopin@op.pl
Thu Sep 11 20:18:00 GMT 2014
- Previous message (by thread): [PATCH] libc/time/gmtime_r.c, libc/time/lcltime_r.c,, libc/time/local.h, libc/time/mktm_r.c: move localtime related functionality, from _mktm_r() to new _mklocaltm_r() to break dependency of gmtime() on, timezones
- Next message (by thread): [PATCH] libc/time/gmtime_r.c, libc/time/lcltime_r.c,, libc/time/local.h, libc/time/mktm_r.c: move localtime related functionality, from _mktm_r() to new _mklocaltm_r() to break dependency of gmtime() on, timezones
- Messages sorted by:
[ date ]
[ thread ]
[ subject ]
[ author ]
W dniu 2014-09-11 21:51, Jeff Johnston pisze:
> Hi Freddie,
>
> Corinna who was looking at this previously is on vacation so I am reviewing it.
Good to know, thanks for your review!
> The only comments I have are:
>
> 1. month_lengths needs to be renamed to be __month_lengths because it is now externalized.
> 2. you might as well be consistent with other files in LIB_SOURCES list of Makefile.am with regards to tabs vs spaces.
Both issues fixed. Updated patch and updated changelog attached.
Regards,
FCh
-------------- next part --------------
2014-09-11 Freddie Chopin <freddie_chopin@op.pl>
* libc\time\month_lengths.c: New file with __month_lengths array
(previously mon_lengths array in mktm_r.c)
* libc\time\tzcalc_limits.c: New file with __tzcalc_limits() from
mktm_r.c
* libc\time\lcltime_r.c (localtime_r): Simplify by changing call to
_mktm_r() with call to gmtime_r() and code moved from _mktm_r() which
was used to do time zone adjustments
* libc\time\gmtime_r.c (gmtime_r): Simplify by moving all relevant
code from _mktm_r(), breaking all dependencies on time zone related
functions
* libc\time\mktm_r.c: Delete file
* libc\time\local.h: Update accordingly - remove declaration of
_mktm_r(), add declaration of __month_lengths[]
* libc\time\Makefile.am: Modify accordingly.
* libc\time\Makefile.in: Regenerate.
-------------- next part --------------
From 4426390a5531e6b3e66e581d1911b9239333fa33 Mon Sep 17 00:00:00 2001
From: Freddie Chopin <freddie.chopin@gmail.com>
Date: Sat, 6 Sep 2014 00:00:12 +0200
Subject: [PATCH] libc/time: Remove dependency of gmtime() on time zone related
code
1. Move mon_lengths array to new file, rename to __month_lengths
2. Move __tzcalc_limits() to new file
3. Move time zone related part of _mktm_r() to localtime_r(), before performing these time zone adjustments call gmtime_r()
4. Move remaining part of _mktm_r() to gmtime_r()
5. Remove mktm_r.c
6. Modify Makefile.am and regenerate Makefile.in
---
newlib/libc/time/Makefile.am | 3 +-
newlib/libc/time/Makefile.in | 30 +++--
newlib/libc/time/gmtime_r.c | 97 +++++++++++++-
newlib/libc/time/lcltime_r.c | 112 +++++++++++++++-
newlib/libc/time/local.h | 3 +-
newlib/libc/time/mktm_r.c | 277 ---------------------------------------
newlib/libc/time/month_lengths.c | 14 ++
newlib/libc/time/tzcalc_limits.c | 77 +++++++++++
8 files changed, 319 insertions(+), 294 deletions(-)
delete mode 100644 newlib/libc/time/mktm_r.c
create mode 100644 newlib/libc/time/month_lengths.c
create mode 100644 newlib/libc/time/tzcalc_limits.c
diff --git a/newlib/libc/time/Makefile.am b/newlib/libc/time/Makefile.am
index 9571631..95f088a 100644
--- a/newlib/libc/time/Makefile.am
+++ b/newlib/libc/time/Makefile.am
@@ -17,10 +17,11 @@ LIB_SOURCES = \
lcltime.c \
lcltime_r.c \
mktime.c \
- mktm_r.c \
+ month_lengths.c \
strftime.c \
strptime.c \
time.c \
+ tzcalc_limits.c \
tzlock.c \
tzset.c \
tzset_r.c \
diff --git a/newlib/libc/time/Makefile.in b/newlib/libc/time/Makefile.in
index c28caaf..48ba064 100644
--- a/newlib/libc/time/Makefile.in
+++ b/newlib/libc/time/Makefile.in
@@ -78,19 +78,20 @@ am__objects_1 = lib_a-asctime.$(OBJEXT) lib_a-asctime_r.$(OBJEXT) \
lib_a-gettzinfo.$(OBJEXT) lib_a-gmtime.$(OBJEXT) \
lib_a-gmtime_r.$(OBJEXT) lib_a-lcltime.$(OBJEXT) \
lib_a-lcltime_r.$(OBJEXT) lib_a-mktime.$(OBJEXT) \
- lib_a-mktm_r.$(OBJEXT) lib_a-strftime.$(OBJEXT) \
+ lib_a-month_lengths.$(OBJEXT) lib_a-strftime.$(OBJEXT) \
lib_a-strptime.$(OBJEXT) lib_a-time.$(OBJEXT) \
- lib_a-tzlock.$(OBJEXT) lib_a-tzset.$(OBJEXT) \
- lib_a-tzset_r.$(OBJEXT) lib_a-tzvars.$(OBJEXT) \
- lib_a-wcsftime.$(OBJEXT)
+ lib_a-tzcalc_limits.$(OBJEXT) lib_a-tzlock.$(OBJEXT) \
+ lib_a-tzset.$(OBJEXT) lib_a-tzset_r.$(OBJEXT) \
+ lib_a-tzvars.$(OBJEXT) lib_a-wcsftime.$(OBJEXT)
@USE_LIBTOOL_FALSE@am_lib_a_OBJECTS = $(am__objects_1)
lib_a_OBJECTS = $(am_lib_a_OBJECTS)
LTLIBRARIES = $(noinst_LTLIBRARIES)
libtime_la_LIBADD =
am__objects_2 = asctime.lo asctime_r.lo clock.lo ctime.lo ctime_r.lo \
difftime.lo gettzinfo.lo gmtime.lo gmtime_r.lo lcltime.lo \
- lcltime_r.lo mktime.lo mktm_r.lo strftime.lo strptime.lo \
- time.lo tzlock.lo tzset.lo tzset_r.lo tzvars.lo wcsftime.lo
+ lcltime_r.lo mktime.lo month_lengths.lo strftime.lo \
+ strptime.lo time.lo tzcalc_limits.lo tzlock.lo tzset.lo \
+ tzset_r.lo tzvars.lo wcsftime.lo
@USE_LIBTOOL_TRUE@am_libtime_la_OBJECTS = $(am__objects_2)
libtime_la_OBJECTS = $(am_libtime_la_OBJECTS)
libtime_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
@@ -277,10 +278,11 @@ LIB_SOURCES = \
lcltime.c \
lcltime_r.c \
mktime.c \
- mktm_r.c \
+ month_lengths.c \
strftime.c \
strptime.c \
time.c \
+ tzcalc_limits.c \
tzlock.c \
tzset.c \
tzset_r.c \
@@ -454,11 +456,11 @@ lib_a-mktime.o: mktime.c
lib_a-mktime.obj: mktime.c
$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-mktime.obj `if test -f 'mktime.c'; then $(CYGPATH_W) 'mktime.c'; else $(CYGPATH_W) '$(srcdir)/mktime.c'; fi`
-lib_a-mktm_r.o: mktm_r.c
- $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-mktm_r.o `test -f 'mktm_r.c' || echo '$(srcdir)/'`mktm_r.c
+lib_a-month_lengths.o: month_lengths.c
+ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-month_lengths.o `test -f 'month_lengths.c' || echo '$(srcdir)/'`month_lengths.c
-lib_a-mktm_r.obj: mktm_r.c
- $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-mktm_r.obj `if test -f 'mktm_r.c'; then $(CYGPATH_W) 'mktm_r.c'; else $(CYGPATH_W) '$(srcdir)/mktm_r.c'; fi`
+lib_a-month_lengths.obj: month_lengths.c
+ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-month_lengths.obj `if test -f 'month_lengths.c'; then $(CYGPATH_W) 'month_lengths.c'; else $(CYGPATH_W) '$(srcdir)/month_lengths.c'; fi`
lib_a-strftime.o: strftime.c
$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-strftime.o `test -f 'strftime.c' || echo '$(srcdir)/'`strftime.c
@@ -478,6 +480,12 @@ lib_a-time.o: time.c
lib_a-time.obj: time.c
$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-time.obj `if test -f 'time.c'; then $(CYGPATH_W) 'time.c'; else $(CYGPATH_W) '$(srcdir)/time.c'; fi`
+lib_a-tzcalc_limits.o: tzcalc_limits.c
+ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-tzcalc_limits.o `test -f 'tzcalc_limits.c' || echo '$(srcdir)/'`tzcalc_limits.c
+
+lib_a-tzcalc_limits.obj: tzcalc_limits.c
+ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-tzcalc_limits.obj `if test -f 'tzcalc_limits.c'; then $(CYGPATH_W) 'tzcalc_limits.c'; else $(CYGPATH_W) '$(srcdir)/tzcalc_limits.c'; fi`
+
lib_a-tzlock.o: tzlock.c
$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-tzlock.o `test -f 'tzlock.c' || echo '$(srcdir)/'`tzlock.c
diff --git a/newlib/libc/time/gmtime_r.c b/newlib/libc/time/gmtime_r.c
index 14c9c76..1111cbc 100644
--- a/newlib/libc/time/gmtime_r.c
+++ b/newlib/libc/time/gmtime_r.c
@@ -1,14 +1,107 @@
/*
* 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>
+ *
+ * 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"
+/* there are 97 leap years in 400-year periods */
+#define DAYS_PER_400_YEARS ((400 - 97) * 365 + 97 * 366)
+/* there are 24 leap years in 100-year periods */
+#define DAYS_PER_100_YEARS ((100 - 24) * 365 + 24 * 366)
+/* there is one leap year every 4 years */
+#define DAYS_PER_4_YEARS (3 * 365 + 366)
+
+static _CONST int days_per_year[4] = {
+ 365, /* 1970 or 1966 */
+ 365, /* 1971 or 1967 */
+ 366, /* 1972 or 1968 */
+ 365 /* 1973 or 1969 */
+} ;
+
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 year;
+ int years400, years100, years4;
+ int yearleap;
+ _CONST int *ip;
+
+ days = ((long)lcltime) / SECSPERDAY;
+ rem = ((long)lcltime) % SECSPERDAY;
+ while (rem < 0)
+ {
+ rem += SECSPERDAY;
+ --days;
+ }
+ while (rem >= SECSPERDAY)
+ {
+ 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 ((res->tm_wday = ((EPOCH_WDAY + days) % DAYSPERWEEK)) < 0)
+ res->tm_wday += DAYSPERWEEK;
+
+ /* compute year & day of year */
+ years400 = days / DAYS_PER_400_YEARS;
+ days -= years400 * DAYS_PER_400_YEARS;
+ years100 = days / DAYS_PER_100_YEARS;
+ days -= years100 * DAYS_PER_100_YEARS;
+ years4 = days / DAYS_PER_4_YEARS;
+ days -= years4 * DAYS_PER_4_YEARS;
+
+ year = EPOCH_YEAR + years400 * 400 + years100 * 100 + years4 * 4;
+
+ /* the value left in days is based in 1970 */
+ if (days < 0)
+ {
+ ip = &days_per_year[3];
+ while (days < 0)
+ {
+ days += *ip--;
+ --year;
+ }
+ }
+ else
+ {
+ ip = &days_per_year[0];
+ while (days >= *ip)
+ {
+ days -= *ip++;
+ ++year;
+ }
+ }
+
+ res->tm_year = year - YEAR_BASE;
+ res->tm_yday = days;
+ yearleap = isleap(year);
+ ip = __month_lengths[yearleap];
+ for (res->tm_mon = 0; days >= ip[res->tm_mon]; ++res->tm_mon)
+ days -= ip[res->tm_mon];
+ res->tm_mday = days + 1;
+
+ res->tm_isdst = 0;
+
+ return (res);
}
diff --git a/newlib/libc/time/lcltime_r.c b/newlib/libc/time/lcltime_r.c
index 9e168aa..9094e5d 100644
--- a/newlib/libc/time/lcltime_r.c
+++ b/newlib/libc/time/lcltime_r.c
@@ -1,12 +1,18 @@
/*
* 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
* broken-down time.
*/
-#include <time.h>
#include "local.h"
struct tm *
@@ -14,5 +20,107 @@ _DEFUN (localtime_r, (tim_p, res),
_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;
+ 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);
}
diff --git a/newlib/libc/time/local.h b/newlib/libc/time/local.h
index 9d9ef87..5fc3ddc 100644
--- a/newlib/libc/time/local.h
+++ b/newlib/libc/time/local.h
@@ -19,9 +19,10 @@
#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];
+
/* locks for multi-threading */
#ifdef __SINGLE_THREAD__
#define TZ_LOCK
diff --git a/newlib/libc/time/mktm_r.c b/newlib/libc/time/mktm_r.c
deleted file mode 100644
index 2668efd..0000000
--- a/newlib/libc/time/mktm_r.c
+++ /dev/null
@@ -1,277 +0,0 @@
-/*
- * mktm_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>
- *
- * 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 <stdlib.h>
-#include <time.h>
-#include "local.h"
-
-/* there are 97 leap years in 400-year periods */
-#define DAYS_PER_400_YEARS ((400 - 97) * 365 + 97 * 366)
-/* there are 24 leap years in 100-year periods */
-#define DAYS_PER_100_YEARS ((100 - 24) * 365 + 24 * 366)
-/* there is one leap year every 4 years */
-#define DAYS_PER_4_YEARS (3 * 365 + 366)
-
-static _CONST int mon_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}
-} ;
-
-static _CONST int days_per_year[4] = {
- 365, /* 1970 or 1966 */
- 365, /* 1971 or 1967 */
- 366, /* 1972 or 1968 */
- 365 /* 1973 or 1969 */
-} ;
-
-struct tm *
-_DEFUN (_mktm_r, (tim_p, res, is_gmtime),
- _CONST time_t * tim_p _AND
- struct tm *res _AND
- int is_gmtime)
-{
- long days, rem;
- time_t lcltime;
- int y;
- int years400, years100, years4;
- int yleap;
- _CONST int *ip;
- __tzinfo_type *tz = __gettzinfo ();
-
- /* base decision about std/dst time on current time */
- lcltime = *tim_p;
-
- days = ((long)lcltime) / SECSPERDAY;
- rem = ((long)lcltime) % SECSPERDAY;
- while (rem < 0)
- {
- rem += SECSPERDAY;
- --days;
- }
- while (rem >= SECSPERDAY)
- {
- 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 ((res->tm_wday = ((EPOCH_WDAY + days) % DAYSPERWEEK)) < 0)
- res->tm_wday += DAYSPERWEEK;
-
- /* compute year & day of year */
- years400 = days / DAYS_PER_400_YEARS;
- days -= years400 * DAYS_PER_400_YEARS;
- years100 = days / DAYS_PER_100_YEARS;
- days -= years100 * DAYS_PER_100_YEARS;
- years4 = days / DAYS_PER_4_YEARS;
- days -= years4 * DAYS_PER_4_YEARS;
-
- y = EPOCH_YEAR + years400 * 400 + years100 * 100 + years4 * 4;
-
- /* the value left in days is based in 1970 */
- if (days < 0)
- {
- ip = &days_per_year[3];
- while (days < 0)
- {
- days += *ip--;
- --y;
- }
- }
- else
- {
- ip = &days_per_year[0];
- while (days >= *ip)
- {
- days -= *ip++;
- ++y;
- }
- }
-
- res->tm_year = y - YEAR_BASE;
- res->tm_yday = days;
- yleap = isleap(y);
- ip = mon_lengths[yleap];
- for (res->tm_mon = 0; days >= ip[res->tm_mon]; ++res->tm_mon)
- days -= ip[res->tm_mon];
- res->tm_mday = days + 1;
-
- if (!is_gmtime)
- {
- long offset;
- int hours, mins, secs;
-
- TZ_LOCK;
- if (_daylight)
- {
- if (y == tz->__tzyear || __tzcalc_limits (y))
- 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 + 1900);
- }
- res->tm_mday = ip[res->tm_mon];
- }
- }
- TZ_UNLOCK;
- }
- else
- res->tm_isdst = 0;
-
- return (res);
-}
-
-int
-_DEFUN (__tzcalc_limits, (year),
- int year)
-{
- int days, year_days, years;
- int i, j;
- __tzinfo_type *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
- {
- int yleap = isleap(year);
- int m_day, m_wday, wday_diff;
- _CONST int *ip = mon_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;
-}
diff --git a/newlib/libc/time/month_lengths.c b/newlib/libc/time/month_lengths.c
new file mode 100644
index 0000000..2871802
--- /dev/null
+++ b/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}
+} ;
diff --git a/newlib/libc/time/tzcalc_limits.c b/newlib/libc/time/tzcalc_limits.c
new file mode 100644
index 0000000..8a0bda3
--- /dev/null
+++ b/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;
+}
--
1.8.1.msysgit.1
- Previous message (by thread): [PATCH] libc/time/gmtime_r.c, libc/time/lcltime_r.c,, libc/time/local.h, libc/time/mktm_r.c: move localtime related functionality, from _mktm_r() to new _mklocaltm_r() to break dependency of gmtime() on, timezones
- Next message (by thread): [PATCH] libc/time/gmtime_r.c, libc/time/lcltime_r.c,, libc/time/local.h, libc/time/mktm_r.c: move localtime related functionality, from _mktm_r() to new _mklocaltm_r() to break dependency of gmtime() on, timezones
- Messages sorted by:
[ date ]
[ thread ]
[ subject ]
[ author ]
More information about the Newlib
mailing list