From 10e58be9828a5e3c059b285f67f837a8b59aaa5b Mon Sep 17 00:00:00 2001 From: Mark Wiebe Date: Wed, 20 Jul 2011 11:54:29 -0500 Subject: [PATCH 1/4] BUG: Build failure on Win32 with mingw This uses the gcc versions of gmtime_s and localtime_s instead of the MS versions when __GNUC__ is defined. --- numpy/core/src/multiarray/datetime_strings.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/numpy/core/src/multiarray/datetime_strings.c b/numpy/core/src/multiarray/datetime_strings.c index 423528b72825..426d4100956a 100644 --- a/numpy/core/src/multiarray/datetime_strings.c +++ b/numpy/core/src/multiarray/datetime_strings.c @@ -131,7 +131,7 @@ parse_iso_8601_datetime(char *str, int len, struct tm tm_; time(&rawtime); -#if defined(_WIN32) +#if defined(_WIN32) && !defined(__GNUC__) if (localtime_s(&tm_, &rawtime) != 0) { PyErr_SetString(PyExc_OSError, "Failed to obtain local time " "from localtime_s"); @@ -532,7 +532,7 @@ parse_iso_8601_datetime(char *str, int len, } /* gmtime converts a 'time_t' into a UTC 'struct tm' */ -#if defined(_WIN32) +#if defined(_WIN32) && !defined(__GNUC__) if (gmtime_s(&tm_, &rawtime) != 0) { PyErr_SetString(PyExc_OSError, "Failed to use gmtime_s to " "get a UTC time"); @@ -884,7 +884,7 @@ make_iso_8601_datetime(npy_datetimestruct *dts, char *outstr, int outlen, rawtime += dts->min * 60; /* localtime converts a 'time_t' into a local 'struct tm' */ -#if defined(_WIN32) +#if defined(_WIN32) && !defined(__GNUC__) if (localtime_s(&tm_, &rawtime) != 0) { PyErr_SetString(PyExc_OSError, "Failed to use localtime_s to " "get a local time"); From 03122fa9c90056597958d933745a0fb053984716 Mon Sep 17 00:00:00 2001 From: Mark Wiebe Date: Wed, 20 Jul 2011 11:55:10 -0500 Subject: [PATCH 2/4] BUG: Fixes build on Win32 with MSVC, thanks to Christoph Gohlke --- numpy/core/src/dummymodule.c | 2 +- numpy/core/src/umath/loops.c.src | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/numpy/core/src/dummymodule.c b/numpy/core/src/dummymodule.c index 595f84d71eb0..8aa4f2f511d9 100644 --- a/numpy/core/src/dummymodule.c +++ b/numpy/core/src/dummymodule.c @@ -42,7 +42,7 @@ PyObject *PyInit__dummy(void) { } #else PyMODINIT_FUNC -init_sort(void) { +init_dummy(void) { Py_InitModule("_dummy", methods); } #endif diff --git a/numpy/core/src/umath/loops.c.src b/numpy/core/src/umath/loops.c.src index e85b24c4244f..0d1841b470ad 100644 --- a/numpy/core/src/umath/loops.c.src +++ b/numpy/core/src/umath/loops.c.src @@ -1169,7 +1169,7 @@ TIMEDELTA_md_m_multiply(char **args, npy_intp *dimensions, npy_intp *steps, void BINARY_LOOP { const npy_timedelta in1 = *(npy_timedelta *)ip1; const double in2 = *(double *)ip2; - if (in1 == NPY_DATETIME_NAT || isnan(in2)) { + if (in1 == NPY_DATETIME_NAT || npy_isnan(in2)) { *((npy_timedelta *)op1) = NPY_DATETIME_NAT; } else { @@ -1184,7 +1184,7 @@ TIMEDELTA_dm_m_multiply(char **args, npy_intp *dimensions, npy_intp *steps, void BINARY_LOOP { const double in1 = *(double *)ip1; const npy_timedelta in2 = *(npy_timedelta *)ip2; - if (isnan(in1) || in2 == NPY_DATETIME_NAT) { + if (npy_isnan(in1) || in2 == NPY_DATETIME_NAT) { *((npy_timedelta *)op1) = NPY_DATETIME_NAT; } else { @@ -1220,7 +1220,7 @@ TIMEDELTA_md_m_divide(char **args, npy_intp *dimensions, npy_intp *steps, void * } else { double result = in1 / in2; - if (isnan(result)) { + if (npy_isnan(result)) { *((npy_timedelta *)op1) = NPY_DATETIME_NAT; } else { From ea6ae36bf7a1729890b24d0f80f2da3eb9099edf Mon Sep 17 00:00:00 2001 From: Mark Wiebe Date: Wed, 20 Jul 2011 16:22:53 -0500 Subject: [PATCH 3/4] BUG: datetime: Use gmtime and localtime for mingw These functions allegedly use thread-local storage on mingw, so hopefully it's ok. --- numpy/core/src/multiarray/datetime_strings.c | 48 ++++++++++++++++++-- 1 file changed, 45 insertions(+), 3 deletions(-) diff --git a/numpy/core/src/multiarray/datetime_strings.c b/numpy/core/src/multiarray/datetime_strings.c index 426d4100956a..d6c60eae554e 100644 --- a/numpy/core/src/multiarray/datetime_strings.c +++ b/numpy/core/src/multiarray/datetime_strings.c @@ -131,7 +131,21 @@ parse_iso_8601_datetime(char *str, int len, struct tm tm_; time(&rawtime); -#if defined(_WIN32) && !defined(__GNUC__) +#if defined(_WIN32) && defined(__GNUC__) + struct tm * tm_ptr; + /* + * MINGW supports neither localtime_s nor localtime_r, but + * supposedly uses thread-local storage, so this should + * be ok. + */ + tm_ptr = localtime(&rawtime); + if (tm_ptr == NULL) { + PyErr_SetString(PyExc_OSError, "Failed to use localtime to " + "get a local time"); + return -1; + } + tm_ = *tm_ptr; +#elif defined(_WIN32) if (localtime_s(&tm_, &rawtime) != 0) { PyErr_SetString(PyExc_OSError, "Failed to obtain local time " "from localtime_s"); @@ -532,7 +546,21 @@ parse_iso_8601_datetime(char *str, int len, } /* gmtime converts a 'time_t' into a UTC 'struct tm' */ -#if defined(_WIN32) && !defined(__GNUC__) +#if defined(_WIN32) && defined(__GNUC__) + struct tm * tm_ptr; + /* + * MINGW supports neither gmtime_s nor gmtime_r, but + * supposedly uses thread-local storage, so this should + * be ok. + */ + tm_ptr = gmtime(&rawtime); + if (tm_ptr == NULL) { + PyErr_SetString(PyExc_OSError, "Failed to use gmtime to " + "get a UTC time"); + goto error; + } + tm_ = *tm_ptr; +#elif defined(_WIN32) if (gmtime_s(&tm_, &rawtime) != 0) { PyErr_SetString(PyExc_OSError, "Failed to use gmtime_s to " "get a UTC time"); @@ -884,7 +912,21 @@ make_iso_8601_datetime(npy_datetimestruct *dts, char *outstr, int outlen, rawtime += dts->min * 60; /* localtime converts a 'time_t' into a local 'struct tm' */ -#if defined(_WIN32) && !defined(__GNUC__) +#if defined(_WIN32) && defined(__GNUC__) + struct tm * tm_ptr; + /* + * MINGW supports neither localtime_s nor localtime_r, but + * supposedly uses thread-local storage, so this should + * be ok. + */ + tm_ptr = localtime(&rawtime); + if (tm_ptr == NULL) { + PyErr_SetString(PyExc_OSError, "Failed to use localtime to " + "get a local time"); + return -1; + } + tm_ = *tm_ptr; +#elif defined(_WIN32) if (localtime_s(&tm_, &rawtime) != 0) { PyErr_SetString(PyExc_OSError, "Failed to use localtime_s to " "get a local time"); From 0ed2d563dbc15747fca946028cf873d5bebf871b Mon Sep 17 00:00:00 2001 From: Mark Wiebe Date: Thu, 21 Jul 2011 16:15:16 -0500 Subject: [PATCH 4/4] BUG: mingw: Another attempt to make mingw NumPy work --- numpy/core/src/multiarray/datetime_strings.c | 47 +++++++++++++++++++- 1 file changed, 46 insertions(+), 1 deletion(-) diff --git a/numpy/core/src/multiarray/datetime_strings.c b/numpy/core/src/multiarray/datetime_strings.c index d6c60eae554e..e804694485fc 100644 --- a/numpy/core/src/multiarray/datetime_strings.c +++ b/numpy/core/src/multiarray/datetime_strings.c @@ -130,9 +130,11 @@ parse_iso_8601_datetime(char *str, int len, time_t rawtime = 0; struct tm tm_; - time(&rawtime); #if defined(_WIN32) && defined(__GNUC__) +/* This is a quagmire in mingw... */ +# if 0 struct tm * tm_ptr; + time(&rawtime); /* * MINGW supports neither localtime_s nor localtime_r, but * supposedly uses thread-local storage, so this should @@ -145,7 +147,21 @@ parse_iso_8601_datetime(char *str, int len, return -1; } tm_ = *tm_ptr; +# else + /* + * Hoping that directly calling the _gmtime64_s and _localtime_s + * functions will allow linking against different MSVC versions. + */ + npy_int64 rawtime64 = 0; + _time64(&rawtime64); + if (_localtime64_s(&tm_, &rawtime64) != 0) { + PyErr_SetString(PyExc_OSError, "Failed to obtain local time " + "from localtime64_s"); + return -1; + } +# endif #elif defined(_WIN32) + time(&rawtime); if (localtime_s(&tm_, &rawtime) != 0) { PyErr_SetString(PyExc_OSError, "Failed to obtain local time " "from localtime_s"); @@ -153,6 +169,7 @@ parse_iso_8601_datetime(char *str, int len, } #else /* Other platforms may require something else */ + time(&rawtime); if (localtime_r(&rawtime, &tm_) == NULL) { PyErr_SetString(PyExc_OSError, "Failed obtain local time " "from localtime_r"); @@ -547,6 +564,8 @@ parse_iso_8601_datetime(char *str, int len, /* gmtime converts a 'time_t' into a UTC 'struct tm' */ #if defined(_WIN32) && defined(__GNUC__) +/* This is a quagmire in mingw... */ +# if 0 struct tm * tm_ptr; /* * MINGW supports neither gmtime_s nor gmtime_r, but @@ -560,6 +579,18 @@ parse_iso_8601_datetime(char *str, int len, goto error; } tm_ = *tm_ptr; +# else + /* + * Hoping that directly calling the _gmtime64_s and _localtime_s + * functions will allow linking against different MSVC versions. + */ + npy_int64 rawtime64 = rawtime; + if (_gmtime64_s(&tm_, &rawtime64) != 0) { + PyErr_SetString(PyExc_OSError, "Failed to obtain UTC time " + "from _gmtime64_s"); + goto error; + } +# endif #elif defined(_WIN32) if (gmtime_s(&tm_, &rawtime) != 0) { PyErr_SetString(PyExc_OSError, "Failed to use gmtime_s to " @@ -913,6 +944,8 @@ make_iso_8601_datetime(npy_datetimestruct *dts, char *outstr, int outlen, /* localtime converts a 'time_t' into a local 'struct tm' */ #if defined(_WIN32) && defined(__GNUC__) +/* This is a quagmire in mingw... */ +# if 0 struct tm * tm_ptr; /* * MINGW supports neither localtime_s nor localtime_r, but @@ -926,6 +959,18 @@ make_iso_8601_datetime(npy_datetimestruct *dts, char *outstr, int outlen, return -1; } tm_ = *tm_ptr; +# else + /* + * Hoping that directly calling the _gmtime64_s and _localtime_s + * functions will allow linking against different MSVC versions. + */ + npy_int64 rawtime64 = rawtime; + if (_localtime64_s(&tm_, &rawtime64) != 0) { + PyErr_SetString(PyExc_OSError, "Failed to obtain local time " + "from _localtime64_s"); + return -1; + } +# endif #elif defined(_WIN32) if (localtime_s(&tm_, &rawtime) != 0) { PyErr_SetString(PyExc_OSError, "Failed to use localtime_s to "