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/