Skip to content

Commit 0d17190

Browse files
pythongh-123681: Check the strftime() behavior at runtime instead of at the compile time
It is needed to support cross-compiling. Remove macros Py_NORMALIZE_CENTURY and Py_STRFTIME_C99_SUPPORT.
1 parent 58e9f95 commit 0d17190

File tree

5 files changed

+42
-177
lines changed

5 files changed

+42
-177
lines changed
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Check the ``strftime()`` behavior at runtime instead of at the compile time
2+
to support cross-compiling. Remove macros Py_NORMALIZE_CENTURY and
3+
Py_STRFTIME_C99_SUPPORT.

Modules/_datetimemodule.c

Lines changed: 39 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1740,6 +1740,42 @@ format_utcoffset(char *buf, size_t buflen, const char *sep,
17401740
return 0;
17411741
}
17421742

1743+
/* Check whether year with century should be normalized for strftime. */
1744+
inline static int
1745+
normalize_century(void)
1746+
{
1747+
static int _normalize_century = -1;
1748+
if (_normalize_century < 0) {
1749+
char year[5];
1750+
struct tm date = {
1751+
.tm_year = -1801,
1752+
.tm_mon = 0,
1753+
.tm_mday = 1
1754+
};
1755+
_normalize_century = (strftime(year, sizeof(year), "%Y", &date) &&
1756+
strcmp(year, "0099") != 0);
1757+
}
1758+
return _normalize_century;
1759+
}
1760+
1761+
/* Check whether C99-specific strftime specifiers are supported. */
1762+
inline static int
1763+
strftime_c99_support(void)
1764+
{
1765+
static int _strftime_c99_support = -1;
1766+
if (_strftime_c99_support < 0) {
1767+
char full_date[11];
1768+
struct tm date = {
1769+
.tm_year = 0,
1770+
.tm_mon = 0,
1771+
.tm_mday = 1
1772+
};
1773+
_strftime_c99_support = (strftime(full_date, sizeof(full_date), "%F", &date) &&
1774+
strcmp(full_date, "1900-01-01") == 0);
1775+
}
1776+
return _strftime_c99_support;
1777+
}
1778+
17431779
static PyObject *
17441780
make_somezreplacement(PyObject *object, char *sep, PyObject *tzinfoarg)
17451781
{
@@ -1910,12 +1946,9 @@ wrap_strftime(PyObject *object, PyObject *format, PyObject *timetuple,
19101946
}
19111947
replacement = freplacement;
19121948
}
1913-
#ifdef Py_NORMALIZE_CENTURY
1914-
else if (ch == 'Y' || ch == 'G'
1915-
#ifdef Py_STRFTIME_C99_SUPPORT
1916-
|| ch == 'F' || ch == 'C'
1917-
#endif
1918-
) {
1949+
else if (normalize_century() && (ch == 'Y' || ch == 'G' ||
1950+
(strftime_c99_support() && (ch == 'F' || ch == 'C'))))
1951+
{
19191952
/* 0-pad year with century as necessary */
19201953
PyObject *item = PySequence_GetItem(timetuple, 0);
19211954
if (item == NULL) {
@@ -1952,15 +1985,11 @@ wrap_strftime(PyObject *object, PyObject *format, PyObject *timetuple,
19521985
* +6 to accommodate dashes, 2-digit month and day for %F. */
19531986
char buf[SIZEOF_LONG * 5 / 2 + 2 + 6];
19541987
Py_ssize_t n = PyOS_snprintf(buf, sizeof(buf),
1955-
#ifdef Py_STRFTIME_C99_SUPPORT
19561988
ch == 'F' ? "%04ld-%%m-%%d" :
1957-
#endif
19581989
"%04ld", year_long);
1959-
#ifdef Py_STRFTIME_C99_SUPPORT
19601990
if (ch == 'C') {
19611991
n -= 2;
19621992
}
1963-
#endif
19641993
if (_PyUnicodeWriter_WriteSubstring(&writer, format, start, end) < 0) {
19651994
goto Error;
19661995
}
@@ -1970,7 +1999,6 @@ wrap_strftime(PyObject *object, PyObject *format, PyObject *timetuple,
19701999
}
19712000
continue;
19722001
}
1973-
#endif
19742002
else {
19752003
/* percent followed by something else */
19762004
continue;

configure

Lines changed: 0 additions & 104 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

configure.ac

Lines changed: 0 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -6644,62 +6644,6 @@ then
66446644
[Define if you have struct stat.st_mtimensec])
66456645
fi
66466646

6647-
AC_CACHE_CHECK([whether year with century should be normalized for strftime], [ac_cv_normalize_century], [
6648-
AC_RUN_IFELSE([AC_LANG_SOURCE([[
6649-
#include <time.h>
6650-
#include <string.h>
6651-
6652-
int main(void)
6653-
{
6654-
char year[5];
6655-
struct tm date = {
6656-
.tm_year = -1801,
6657-
.tm_mon = 0,
6658-
.tm_mday = 1
6659-
};
6660-
if (strftime(year, sizeof(year), "%Y", &date) && !strcmp(year, "0099")) {
6661-
return 1;
6662-
}
6663-
return 0;
6664-
}
6665-
]])],
6666-
[ac_cv_normalize_century=yes],
6667-
[ac_cv_normalize_century=no],
6668-
[ac_cv_normalize_century=yes])])
6669-
if test "$ac_cv_normalize_century" = yes
6670-
then
6671-
AC_DEFINE([Py_NORMALIZE_CENTURY], [1],
6672-
[Define if year with century should be normalized for strftime.])
6673-
fi
6674-
6675-
AC_CACHE_CHECK([whether C99-specific strftime specifiers are supported], [ac_cv_strftime_c99_support], [
6676-
AC_RUN_IFELSE([AC_LANG_SOURCE([[
6677-
#include <time.h>
6678-
#include <string.h>
6679-
6680-
int main(void)
6681-
{
6682-
char full_date[11];
6683-
struct tm date = {
6684-
.tm_year = 0,
6685-
.tm_mon = 0,
6686-
.tm_mday = 1
6687-
};
6688-
if (strftime(full_date, sizeof(full_date), "%F", &date) && !strcmp(full_date, "1900-01-01")) {
6689-
return 0;
6690-
}
6691-
return 1;
6692-
}
6693-
]])],
6694-
[ac_cv_strftime_c99_support=yes],
6695-
[ac_cv_strftime_c99_support=no],
6696-
[ac_cv_strftime_c99_support=no])])
6697-
if test "$ac_cv_strftime_c99_support" = yes
6698-
then
6699-
AC_DEFINE([Py_STRFTIME_C99_SUPPORT], [1],
6700-
[Define if C99-specific strftime specifiers are supported.])
6701-
fi
6702-
67036647
dnl check for ncursesw/ncurses and panelw/panel
67046648
dnl NOTE: old curses is not detected.
67056649
dnl have_curses=[no, yes]

pyconfig.h.in

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1706,18 +1706,12 @@
17061706
/* Defined if _Complex C type is available. */
17071707
#undef Py_HAVE_C_COMPLEX
17081708

1709-
/* Define if year with century should be normalized for strftime. */
1710-
#undef Py_NORMALIZE_CENTURY
1711-
17121709
/* Define if rl_startup_hook takes arguments */
17131710
#undef Py_RL_STARTUP_HOOK_TAKES_ARGS
17141711

17151712
/* Define if you want to enable internal statistics gathering. */
17161713
#undef Py_STATS
17171714

1718-
/* Define if C99-specific strftime specifiers are supported. */
1719-
#undef Py_STRFTIME_C99_SUPPORT
1720-
17211715
/* The version of SunOS/Solaris as reported by `uname -r' without the dot. */
17221716
#undef Py_SUNOS_VERSION
17231717

0 commit comments

Comments
 (0)