[前][次][番号順一覧][スレッド一覧]

ruby-changes:23297

From: nobu <ko1@a...>
Date: Mon, 16 Apr 2012 16:22:54 +0900 (JST)
Subject: [ruby-changes:23297] nobu:r35348 (trunk): * win32/win32.c (gmtime_r, localtime_r): POSIX compliant reentrant

nobu	2012-04-16 16:22:43 +0900 (Mon, 16 Apr 2012)

  New Revision: 35348

  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=35348

  Log:
    * win32/win32.c (gmtime_r, localtime_r): POSIX compliant reentrant
      versions.

  Modified files:
    trunk/ChangeLog
    trunk/configure.in
    trunk/include/ruby/win32.h
    trunk/win32/Makefile.sub
    trunk/win32/win32.c

Index: include/ruby/win32.h
===================================================================
--- include/ruby/win32.h	(revision 35347)
+++ include/ruby/win32.h	(revision 35348)
@@ -690,6 +690,9 @@
 
 int rb_w32_times(struct tms *);
 
+struct tm *gmtime_r(const time_t *, struct tm *);
+struct tm *localtime_r(const time_t *, struct tm *);
+
 /* thread stuff */
 int  rb_w32_sleep(unsigned long msec);
 int  rb_w32_putc(int, FILE*);
Index: configure.in
===================================================================
--- configure.in	(revision 35347)
+++ configure.in	(revision 35348)
@@ -1089,6 +1089,7 @@
 		rb_cv_negative_time_t=no
 		ac_cv_func_fcntl=yes
 		ac_cv_func_flock=yes
+		ac_cv_func_gmtime_r=yes
 		rb_cv_large_fd_select=yes
 		AC_LIBOBJ([langinfo])
 		: ${enable_win95=maybe}
Index: ChangeLog
===================================================================
--- ChangeLog	(revision 35347)
+++ ChangeLog	(revision 35348)
@@ -1,5 +1,8 @@
-Mon Apr 16 16:08:18 2012  Nobuyoshi Nakada  <nobu@r...>
+Mon Apr 16 16:22:40 2012  Nobuyoshi Nakada  <nobu@r...>
 
+	* win32/win32.c (gmtime_r, localtime_r): POSIX compliant reentrant
+	  versions.
+
 	* configure.in (RUBY_MSVCRT_VERSION): define on mingw too.
 
 	* win32/Makefile.sub (config.h): prefix RT_VER with RUBY and make
Index: win32/win32.c
===================================================================
--- win32/win32.c	(revision 35347)
+++ win32/win32.c	(revision 35348)
@@ -6257,3 +6257,108 @@
 rb_w32_fd_is_text(int fd) {
     return _osfile(fd) & FTEXT;
 }
+
+#if RUBY_MSVCRT_VERSION < 80
+static int
+unixtime_to_systemtime(const time_t t, SYSTEMTIME *st)
+{
+    FILETIME ft;
+    if (unixtime_to_filetime(t, &ft)) return -1;
+    if (!FileTimeToSystemTime(&ft, st)) return -1;
+    return 0;
+}
+
+static void
+systemtime_to_tm(const SYSTEMTIME *st, struct tm *t)
+{
+    int y = st->wYear, m = st->wMonth, d = st->wDay;
+    t->tm_sec  = st->wSecond;
+    t->tm_min  = st->wMinute;
+    t->tm_hour = st->wHour;
+    t->tm_mday = st->wDay;
+    t->tm_mon  = st->wMonth - 1;
+    t->tm_year = y - 1900;
+    t->tm_wday = st->wDayOfWeek;
+    switch (m) {
+      case 1:
+	break;
+      case 2:
+	d += 31;
+	break;
+      default:
+	d += 31 + 28 + (!(y % 4) && ((y % 100) || !(y % 400)));
+	d += ((m - 3) * 153 + 2) / 5;
+	break;
+    }
+    t->tm_yday = d - 1;
+}
+
+static int
+systemtime_to_localtime(TIME_ZONE_INFORMATION *tz, SYSTEMTIME *gst, SYSTEMTIME *lst)
+{
+    TIME_ZONE_INFORMATION stdtz;
+    SYSTEMTIME sst;
+
+    if (!SystemTimeToTzSpecificLocalTime(tz, gst, lst)) return -1;
+    if (!tz) {
+	GetTimeZoneInformation(&stdtz);
+	tz = &stdtz;
+    }
+    if (tz->StandardBias == tz->DaylightBias) return 0;
+    if (!tz->StandardDate.wMonth) return 0;
+    if (!tz->DaylightDate.wMonth) return 0;
+    if (tz != &stdtz) stdtz = *tz;
+
+    stdtz.StandardDate.wMonth = stdtz.DaylightDate.wMonth = 0;
+    if (!SystemTimeToTzSpecificLocalTime(&stdtz, gst, &sst)) return 0;
+    if (lst->wMinute == sst.wMinute && lst->wHour == sst.wHour)
+	return 0;
+    return 1;
+}
+#endif
+
+struct tm *
+gmtime_r(const time_t *tp, struct tm *rp)
+{
+    int e = EINVAL;
+    if (!tp || !rp) {
+      error:
+	errno = e;
+	return NULL;
+    }
+#if RUBY_MSVCRT_VERSION >= 80
+    e = gmtime_s(rp, tp);
+    if (e != 0) goto error;
+#else
+    {
+	SYSTEMTIME st;
+	if (unixtime_to_systemtime(*tp, &st)) goto error;
+	rp->tm_isdst = 0;
+	systemtime_to_tm(&st, rp);
+    }
+#endif
+    return rp;
+}
+
+struct tm *
+localtime_r(const time_t *tp, struct tm *rp)
+{
+    int e = EINVAL;
+    if (!tp || !rp) {
+      error:
+	errno = e;
+	return NULL;
+    }
+#if RUBY_MSVCRT_VERSION >= 80
+    e = localtime_s(rp, tp);
+    if (e) goto error;
+#else
+    {
+	SYSTEMTIME gst, lst;
+	if (unixtime_to_systemtime(*tp, &gst)) goto error;
+	rp->tm_isdst = systemtime_to_localtime(NULL, &gst, &lst);
+	systemtime_to_tm(&lst, rp);
+    }
+#endif
+    return rp;
+}
Index: win32/Makefile.sub
===================================================================
--- win32/Makefile.sub	(revision 35347)
+++ win32/Makefile.sub	(revision 35348)
@@ -651,6 +651,7 @@
 #define HAVE_SIGNBIT 1
 #define HAVE_TZNAME 1
 #define HAVE_DAYLIGHT 1
+#define HAVE_GMTIME_R 1
 #define SETPGRP_VOID 1
 #define RSHIFT(x,y) ((x)>>(int)y)
 #define HAVE_RB_FD_INIT 1

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]