From 8c59a9eb5cdd49322c399601bcbee630321164de Mon Sep 17 00:00:00 2001 From: Bruno Haible Date: Sun, 30 Apr 2017 13:19:24 +0200 Subject: [PATCH] ctime: New module. * lib/time.in.h (ctime): New declaration. * lib/ctime.c: New file. * m4/ctime.m4: New file. * m4/time_h.m4 (gl_HEADER_TIME_H_DEFAULTS): Initialize GNULIB_CTIME, REPLACE_CTIME. * modules/time (Makefile.am): Substitute GNULIB_CTIME, REPLACE_CTIME. * modules/ctime: New file. * doc/posix-functions/ctime.texi: Mention the new module. --- ChangeLog | 12 ++++++++++ doc/posix-functions/ctime.texi | 8 +++---- lib/ctime.c | 40 ++++++++++++++++++++++++++++++++++ lib/time.in.h | 16 ++++++++++++++ m4/ctime.m4 | 15 +++++++++++++ m4/time_h.m4 | 4 +++- modules/ctime | 27 +++++++++++++++++++++++ modules/time | 2 ++ 8 files changed, 119 insertions(+), 5 deletions(-) create mode 100644 lib/ctime.c create mode 100644 m4/ctime.m4 create mode 100644 modules/ctime diff --git a/ChangeLog b/ChangeLog index 69b8ae78ad..17c3bf6e84 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,15 @@ +2017-04-30 Bruno Haible + + ctime: New module. + * lib/time.in.h (ctime): New declaration. + * lib/ctime.c: New file. + * m4/ctime.m4: New file. + * m4/time_h.m4 (gl_HEADER_TIME_H_DEFAULTS): Initialize GNULIB_CTIME, + REPLACE_CTIME. + * modules/time (Makefile.am): Substitute GNULIB_CTIME, REPLACE_CTIME. + * modules/ctime: New file. + * doc/posix-functions/ctime.texi: Mention the new module. + 2017-04-30 Bruno Haible gettimeofday: Provide higher resolution on native Windows. diff --git a/doc/posix-functions/ctime.texi b/doc/posix-functions/ctime.texi index e54a7b5b8e..6abc4c4b53 100644 --- a/doc/posix-functions/ctime.texi +++ b/doc/posix-functions/ctime.texi @@ -4,18 +4,18 @@ POSIX specification:@* @url{http://www.opengroup.org/onlinepubs/9699919799/functions/ctime.html} -Gnulib module: --- +Gnulib module: ctime Portability problems fixed by Gnulib: @itemize +@item +On native Windows platforms (mingw, MSVC), this function works incorrectly +when the environment variable @code{TZ} has been set by Cygwin. @end itemize Portability problems not fixed by Gnulib: @itemize @item -On native Windows platforms (mingw, MSVC), this function works incorrectly -when the environment variable @code{TZ} has been set by Cygwin. -@item This function may overflow its internal buffer if an invalid year is passed. @item The @code{ctime} function need not be reentrant, and consequently is diff --git a/lib/ctime.c b/lib/ctime.c new file mode 100644 index 0000000000..16416ab8f4 --- /dev/null +++ b/lib/ctime.c @@ -0,0 +1,40 @@ +/* Work around platform bugs in ctime. + Copyright (C) 2017 Free Software Foundation, Inc. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +#include + +/* Specification. */ +#include + +#include +#include + +#undef ctime + +char * +rpl_ctime (const time_t *tp) +{ +#if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__ + /* If the environment variable TZ has been set by Cygwin, neutralize it. + The Microsoft CRT interprets TZ differently than Cygwin and produces + incorrect results if TZ has the syntax used by Cygwin. */ + const char *tz = getenv ("TZ"); + if (tz != NULL && strchr (tz, '/') != NULL) + _putenv ("TZ="); +#endif + + return ctime (tp); +} diff --git a/lib/time.in.h b/lib/time.in.h index 86436c2276..47087d8da6 100644 --- a/lib/time.in.h +++ b/lib/time.in.h @@ -233,6 +233,22 @@ _GL_CXXALIAS_SYS (strptime, char *, (char const *restrict __buf, _GL_CXXALIASWARN (strptime); # endif +/* Convert *TP to a date and time string. See + . */ +# if @GNULIB_CTIME@ +# if @REPLACE_CTIME@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# define ctime rpl_ctime +# endif +_GL_FUNCDECL_RPL (ctime, char *, (time_t const *__tp) + _GL_ARG_NONNULL ((1))); +_GL_CXXALIAS_RPL (ctime, char *, (time_t const *__tp)); +# else +_GL_CXXALIAS_SYS (ctime, char *, (time_t const *__tp)); +# endif +_GL_CXXALIASWARN (ctime); +# endif + # if defined _GNU_SOURCE && @GNULIB_TIME_RZ@ && ! @HAVE_TIMEZONE_T@ typedef struct tm_zone *timezone_t; _GL_FUNCDECL_SYS (tzalloc, timezone_t, (char const *__name)); diff --git a/m4/ctime.m4 b/m4/ctime.m4 new file mode 100644 index 0000000000..2d4b3f82ed --- /dev/null +++ b/m4/ctime.m4 @@ -0,0 +1,15 @@ +# ctime.m4 serial 1 +dnl Copyright (C) 2017 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +AC_DEFUN([gl_FUNC_CTIME], +[ + AC_REQUIRE([gl_HEADER_TIME_H_DEFAULTS]) + AC_REQUIRE([AC_CANONICAL_HOST]) + case "$host_os" in + mingw*) REPLACE_CTIME=1 ;; + *) REPLACE_CTIME=0 ;; + esac +]) diff --git a/m4/time_h.m4 b/m4/time_h.m4 index b92567875c..fdd819bc59 100644 --- a/m4/time_h.m4 +++ b/m4/time_h.m4 @@ -2,7 +2,7 @@ # Copyright (C) 2000-2001, 2003-2007, 2009-2017 Free Software Foundation, Inc. -# serial 9 +# serial 10 # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -104,6 +104,7 @@ AC_DEFUN([gl_TIME_MODULE_INDICATOR], AC_DEFUN([gl_HEADER_TIME_H_DEFAULTS], [ + GNULIB_CTIME=0; AC_SUBST([GNULIB_CTIME]) GNULIB_MKTIME=0; AC_SUBST([GNULIB_MKTIME]) GNULIB_NANOSLEEP=0; AC_SUBST([GNULIB_NANOSLEEP]) GNULIB_STRPTIME=0; AC_SUBST([GNULIB_STRPTIME]) @@ -118,6 +119,7 @@ AC_DEFUN([gl_HEADER_TIME_H_DEFAULTS], dnl If another module says to replace or to not replace, do that. dnl Otherwise, replace only if someone compiles with -DGNULIB_PORTCHECK; dnl this lets maintainers check for portability. + REPLACE_CTIME=GNULIB_PORTCHECK; AC_SUBST([REPLACE_CTIME]) REPLACE_LOCALTIME_R=GNULIB_PORTCHECK; AC_SUBST([REPLACE_LOCALTIME_R]) REPLACE_MKTIME=GNULIB_PORTCHECK; AC_SUBST([REPLACE_MKTIME]) REPLACE_NANOSLEEP=GNULIB_PORTCHECK; AC_SUBST([REPLACE_NANOSLEEP]) diff --git a/modules/ctime b/modules/ctime new file mode 100644 index 0000000000..d700ca87a6 --- /dev/null +++ b/modules/ctime @@ -0,0 +1,27 @@ +Description: +ctime() function: convert time to string. + +Files: +lib/ctime.c +m4/ctime.m4 + +Depends-on: +time + +configure.ac: +gl_FUNC_CTIME +if test $REPLACE_CTIME = 1; then + AC_LIBOBJ([ctime]) +fi +gl_TIME_MODULE_INDICATOR([ctime]) + +Makefile.am: + +Include: + + +License: +LGPLv2+ + +Maintainer: +all diff --git a/modules/time b/modules/time index d12add0911..eff6132fd2 100644 --- a/modules/time +++ b/modules/time @@ -30,6 +30,7 @@ time.h: time.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H) $( -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \ -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \ -e 's|@''NEXT_TIME_H''@|$(NEXT_TIME_H)|g' \ + -e 's/@''GNULIB_CTIME''@/$(GNULIB_CTIME)/g' \ -e 's/@''GNULIB_GETTIMEOFDAY''@/$(GNULIB_GETTIMEOFDAY)/g' \ -e 's/@''GNULIB_MKTIME''@/$(GNULIB_MKTIME)/g' \ -e 's/@''GNULIB_NANOSLEEP''@/$(GNULIB_NANOSLEEP)/g' \ @@ -42,6 +43,7 @@ time.h: time.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H) $( -e 's|@''HAVE_STRPTIME''@|$(HAVE_STRPTIME)|g' \ -e 's|@''HAVE_TIMEGM''@|$(HAVE_TIMEGM)|g' \ -e 's|@''HAVE_TIMEZONE_T''@|$(HAVE_TIMEZONE_T)|g' \ + -e 's|@''REPLACE_CTIME''@|$(REPLACE_CTIME)|g' \ -e 's|@''REPLACE_GMTIME''@|$(REPLACE_GMTIME)|g' \ -e 's|@''REPLACE_LOCALTIME''@|$(REPLACE_LOCALTIME)|g' \ -e 's|@''REPLACE_LOCALTIME_R''@|$(REPLACE_LOCALTIME_R)|g' \ -- 2.39.5